Home avatar

Miles Chou

天涯何處無幹話,何必要講實務話

導入驗收測試(一)

導入 Composer 的時候,我們有新增一個範例的單元測試。如果可以的話,下一步當然就是開始寫一些基本的單元測試,來保護系統元件。但,並不是每個專案都能這麼開心,如果真的無法寫單元測試的話該怎麼辦呢?沒關係,我們還能寫驗收測試!

Faker(6)--自己 Provider 自己來

一個套件好不好用,除了它本身的功能要很厲害之外,我們也能藉由擴充功能的方法來讓套件更強大,那就再好也不過了。這正是開關原則的精神,而 Faker 正是符合此精神的套件。

就讓我們一起來證明它吧!

世間情是一部八點檔連續劇,我們來試看看能不能做出一個世間情產生器,可以產生世間情的角色名字。

照 Faker 的設計,我們只需要寫一個 Provider,再加入 Generator 即可。

我們會有兩種做法,一種是全新的 Provider 與方法,另一種是繼承 Person 並覆寫原本的 name 方法。

這個方法非常簡單,先寫 Provider,並定義好公開要讓 Generator 參考的方法(loveName):

Faker(5)--Provider 們不要起爭議

Faker 提供的 Provider 非常多,除了預設之外,還有不同語系實作。

不過我們先來解決昨天的疑惑:這些 Provider 到底是如何使用 Generator 的?

搜尋了一下,會發現 Provider 大部分會使用 Generatorparse() 方法,而 Day 7 有提到,它的本質是 format()。換句話說,Provider 會經由 Generator 來存取其他 Provider。

這個設計有點類似 Mediator Pattern,它們的關係如下:

classDiagram
    class Client
    class Base {
        # generator Generator
    }
    class Provider1
    class Provider2
    class Generator
    Client --> Generator
    Base <|-- Provider1
    Base <|-- Provider2
    Base --> Generator : Midiator
    Generator --> Provider1
    Generator --> Provider2

Provider 要使用 Generator 當 Mediator 時,必須小心循環呼叫的問題,比方說 A Provider 呼叫 B Provider,而 B Provider 又要呼叫 A Provider。

Faker(4)--Provider 與 Generator 之間的愛恨情仇

如果有認真看前兩天的文章,應該會發現一個很奇怪的事:

  • Day 7 提到:Factory 產生 Generator 物件時,會使用 addProvider()Provider 加入 Generator
  • Day 8 提到:Provider\Base 建構子的依賴是 Generator

這造成了一個循環引用的關係

classDiagram
    class ProviderBase["Provider\Base"]
    class Generator
    ProviderBase --> Generator
    Generator --> ProviderBase

通常這樣的關係是不利於維護的,容易修改一個地方,而讓很多地方同時受影響。不過我們還是先一起來看看它到底在做什麼吧!

關於 Generator 使用 Provider 的部分,Day 7 已經有說明,不再贅述。

打開 IDE 搜尋一下,會發現 Provider\Base 有 3 個方法會用到 Generator

  • optional()
  • unique()
  • valid()

與其他產生假資料的方法不同的是:這三個方法會回傳 Generator 物件或是另外三種 Generator 物件:

先來了解這三個方法在做什麼:

optional() 方法需要給一個權重值(百分比)與一個預設值(default),它會依權重值來隨機決定要回傳 DefaultGenerator 還是正常的 Generator

先來看個簡單的範例: