<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 仿件對象(Mock Object) 將對象替換為能驗證預期行為(例如斷言某個方法必會被調用)的測試替身的實踐方法稱為*模仿(mocking)*。 可以用 *仿件對象(mock object)*“作為觀察點來核實被測試系統在測試中的間接輸出。通常,仿件對象還需要包括樁件的功能,因為如果測試尚未失敗則仿件對象需要向被測系統返回一些值,但是其重點還是在對間接輸出的核實上。因此,仿件對象遠不止是樁件加斷言,它是以一種從根本上完全不同的方式來使用的”(Gerard Meszaros)。 ### 局限性:對預期的自動校驗 PHPUnit只會對在某個測試的作用域內生成的仿件對象進行自動校驗。諸如在數據供給器內生成或用`@depends` 標注注入測試的仿件對象,PHPUnit并不會自動對其進行校驗。 這有個例子:假設需要測試的當前方法,在例子中是 `update()`,確實在一個觀察著另外一個對象的對象中上被調用了。[Example?9.10, “被測系統(SUT)中 Subject 與 Observer 類的代碼”](# "Example?9.10.?被測系統(SUT)中 Subject 與 Observer 類的代碼")展示了被測系統(SUT)中 `Subject` 和 `Observer` 兩個類的代碼。 **Example?9.10.?被測系統(SUT)中 Subject 與 Observer 類的代碼** ~~~ <?php class Subject { protected $observers = array(); protected $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } public function attach(Observer $observer) { $this->observers[] = $observer; } public function doSomething() { // 做點什么。 // ... // 通知觀察者。 $this->notify('something'); } public function doSomethingBad() { foreach ($this->observers as $observer) { $observer->reportError(42, 'Something bad happened', $this); } } protected function notify($argument) { foreach ($this->observers as $observer) { $observer->update($argument); } } // 其他方法。 } class Observer { public function update($argument) { // 做點什么。 } public function reportError($errorCode, $errorMessage, Subject $subject) { // 做點什么。 } // 其他方法。 } ?> ~~~ [Example?9.11, “測試某個方法會以特定參數被調用一次”](# "Example?9.11.?測試某個方法會以特定參數被調用一次")展示了如何用仿件對象來測試 `Subject` 和 `Observer` 對象之間的互動。 首先用 `PHPUnit_Framework_TestCase` 類提供的 `getMock()` 方法建立 `Observer` 的仿件對象。由于給出了一個數組做為 `getMock()` 方法的第二(可選)參數,`Observer` 類只有 `update()` 方法會被替換為仿實現。 由于關注的是檢驗某個方法是否被調用,以及調用時具體所使用的參數,因此引入 `expects()` 與 `with()` 方法來指明此交互應該是什么樣的。 **Example?9.11.?測試某個方法會以特定參數被調用一次** ~~~ <?php class SubjectTest extends PHPUnit_Framework_TestCase { public function testObserversAreUpdated() { // 為 Observer 類建立仿件對象,只模仿 update() 方法。 $observer = $this->getMockBuilder('Observer') ->setMethods(array('update')) ->getMock(); // 建立預期狀況:update() 方法將會被調用一次, // 并且將以字符串 'something' 為參數。 $observer->expects($this->once()) ->method('update') ->with($this->equalTo('something')); // 創建 Subject 對象,并將模仿的 Observer 對象連接其上。 $subject = new Subject('My subject'); $subject->attach($observer); // 在 $subject 對象上調用 doSomething() 方法, // 預期將以字符串 'something' 為參數調用 // Observer 仿件對象的 update() 方法。 $subject->doSomething(); } } ?> ~~~ `with()` 方法可以攜帶任何數量的參數,對應于被模仿的方法的參數數量。可以對方法的參數指定更加高等的約束而不僅是簡單的匹配。 **Example?9.12.?測試某個方法將會以特定數量的參數進行調用,并且對各個參數以多種方式進行約束** ~~~ <?php class SubjectTest extends PHPUnit_Framework_TestCase { public function testErrorReported() { // 為 Observer 類建立仿件,對 reportError() 方法進行模仿 $observer = $this->getMockBuilder('Observer') ->setMethods(array('reportError')) ->getMock(); $observer->expects($this->once()) ->method('reportError') ->with( $this->greaterThan(0), $this->stringContains('Something'), $this->anything() ); $subject = new Subject('My subject'); $subject->attach($observer); // doSomethingBad() 方法應當會通過(observer的)reportError()方法 //向 observer 報告錯誤。 $subject->doSomethingBad(); } } ?> ~~~ `withConsecutive()` 方法可以接受任意多個數組作為參數,具體數量取決于欲測試的調用。每個數組都都是對被仿方法的相應參數的一組約束,就像 `with()` 中那樣。 **Example?9.13.?測試某個方法將會以特定參數被調用二次** ~~~ <?php class FooTest extends PHPUnit_Framework_TestCase { public function testFunctionCalledTwoTimesWithSpecificArguments() { $mock = $this->getMockBuilder('stdClass') ->setMethods(array('set')) ->getMock(); $mock->expects($this->exactly(2)) ->method('set') ->withConsecutive( array($this->equalTo('foo'), $this->greaterThan(0)), array($this->equalTo('bar'), $this->greaterThan(0)) ); $mock->set('foo', 21); $mock->set('bar', 48); } } ?> ~~~ `callback()` 約束用來進行更加復雜的參數校驗。此約束的唯一參數是一個 PHP 回調項(callback)。此 PHP 回調項接受需要校驗的參數作為其唯一參數,并應當在參數通過校驗時返回 `TRUE`,否則返回 `FALSE`。 **Example?9.14.?更加復雜的參數校驗** ~~~ <?php class SubjectTest extends PHPUnit_Framework_TestCase { public function testErrorReported() { // 為 Observer 類建立仿件,模仿 reportError() 方法 $observer = $this->getMockBuilder('Observer') ->setMethods(array('reportError')) ->getMock(); $observer->expects($this->once()) ->method('reportError') ->with($this->greaterThan(0), $this->stringContains('Something'), $this->callback(function($subject){ return is_callable(array($subject, 'getName')) && $subject->getName() == 'My subject'; })); $subject = new Subject('My subject'); $subject->attach($observer); // doSomethingBad() 方法應當會通過(observer的)reportError()方法 //向 observer 報告錯誤。 $subject->doSomethingBad(); } } ?> ~~~ **Example?9.15.?測試某個方法將會被調用一次,并且以某個特定對象作為參數。** ~~~ <?php class FooTest extends PHPUnit_Framework_TestCase { public function testIdenticalObjectPassed() { $expectedObject = new stdClass; $mock = $this->getMockBuilder('stdClass') ->setMethods(array('foo')) ->getMock(); $mock->expects($this->once()) ->method('foo') ->with($this->identicalTo($expectedObject)); $mock->foo($expectedObject); } } ?> ~~~ **Example?9.16.?創建仿件對象時啟用參數克隆** ~~~ <?php class FooTest extends PHPUnit_Framework_TestCase { public function testIdenticalObjectPassed() { $cloneArguments = true; $mock = $this->getMockBuilder('stdClass') ->enableArgumentCloning() ->getMock(); // 現在仿件將對參數進行克隆,因此 identicalTo 約束將會失敗。 } } ?> ~~~ [Table?A.1, “約束條件”](# "Table?A.1.?約束條件")列出了可以應用于方法參數的各種約束,[Table?9.1, “匹配器”](# "Table?9.1.?匹配器")列出了可以用于指定調用次數的各種匹配器。 **Table?9.1.?匹配器** | 匹配器 | 含義 | |-----|-----| | PHPUnit_Framework_MockObject_Matcher_AnyInvokedCount any() | 返回一個匹配器,當被評定的方法執行0次或更多次(即任意次數)時匹配成功。 | | PHPUnit_Framework_MockObject_Matcher_InvokedCount never() | 返回一個匹配器,當被評定的方法從未執行時匹配成功。 | | PHPUnit_Framework_MockObject_Matcher_InvokedAtLeastOnce atLeastOnce()` | 返回一個匹配器,當被評定的方法執行至少一次時匹配成功。 | | PHPUnit_Framework_MockObject_Matcher_InvokedCount once() | 返回一個匹配器,當被評定的方法執行恰好一次時匹配成功。 | | PHPUnit_Framework_MockObject_Matcher_InvokedCount exactly(int $count) | 返回一個匹配器,當被評定的方法執行恰好 `$count` 次時匹配成功。 | | PHPUnit_Framework_MockObject_Matcher_InvokedAtIndex at(int $index) | 返回一個匹配器,當被評定的方法是第 `$index` 個執行的方法時匹配成功。 | >[info] ### Note > `at()` 匹配器的 `$index` 參數指的是對給定仿件對象的*所有方法的調用*的索引,從零開始。使用這個匹配器要謹慎,因為它可能導致測試由于與具體的實現細節過分緊密綁定而變得脆弱。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看