Несмотря на то, что на этот вопрос уже дан полный ответ (как установить атрибут объекта, переданного в качестве аргумента для mock), я думаю, стоит отметить, что PHPUnit поддерживает ограничение обратного вызова, которое передается с помощью ().
Я продолжал сталкиваться с этим потоком, пытаясь выяснить, как выполнить дальнейшие утверждения для аргументов макета объекта. Например, мне нужно было проверить возвращаемое значение какого-либо метода. Очевидно, что для здравого смысла нет метода methodReturnValueEqualTo (), эквивалентного утверждению атрибута, использованному в ответе выше.
К счастью, PHPUnit поддерживает (как минимум 3.7) ограничение обратного вызова, которое имеет большой смысл и его можно найти в специализированных библиотеках Mock, таких как Mockery .
Текущая Версия PHPUnit docs заявляет следующее:
Ограничение callback () может использоваться для более сложной проверки аргументов. Это ограничение принимает обратный вызов PHP в качестве единственного аргумента. Обратный вызов PHP получит аргумент, подлежащий проверке, в качестве единственного аргумента и должен вернуть TRUE, если аргумент проходит проверку, и FALSE в противном случае.
Поэтому, используя ограничение обратного вызова, пример OP теперь можно выразить как:
class SuTTest extends PHPUnit_Framework_TestCase {
public function testSuT () {
$stub = $this->getMock('Some');
$stub->expects($this->once())
->method('callMe')
->with($this->callback(function($arg) {
return ($arg instanceof Some) && ($arg->att === 'hi');
})
);
/*
* Will $stub->callMe be called with a Foo object whose $att is 'hi'?
*/
$sut = new SuT();
$sut->testMe($stub);
}
}
И провал теста будет выглядеть примерно так:
1) SuTTest :: testSuT
Ожидание не удалось для имени метода равно при вызове 1 раз (а)
Параметр 0 для вызова Some :: callMe (Foo Object (...)) не соответствует ожидаемому значению.
Не удалось утверждать, что Foo Object () принят указанным обратным вызовом.
Теперь вы можете использовать любую логику для этого аргумента.
Еще лучше, несмотря на то, что это не документированная функция в документах PHPUnit, вы можете использовать утверждения и получать преимущества от сообщений об ошибках утверждений:
class SuTTest extends PHPUnit_Framework_TestCase {
public function testSuT () {
// alias to circumvent php closure lexical variable restriction
$test = $this;
// proceed as normal
$stub = $this->getMock('Some');
$stub->expects($this->once())
->method('callMe')
// inject the test case in the closure
->with($this->callback(function($arg) use ($test) {
// use test assertions
$test->assertInstanceOf('Some', $arg);
$test->assertAttributeEquals('hi', 'att', $arg);
// return true to satisfy constraint if all assertions passed
return true;
})
);
/*
* Will $stub->callMe be called with a Foo object whose $att is 'hi'?
*/
$sut = new SuT();
$sut->testMe( $stub );
}
}
На самом деле не знаю, насколько будущей является стратегия , использующая утверждения и возвращающая true . Это не задокументировано, и в сообщении об ошибке есть компромисс. Вы больше не получаете сообщение об ограничении параметров, поэтому, если вы устанавливаете утверждения для нескольких аргументов, вам придется по возможности вывести, какой из них не удался. Но вы получите лучшее описание ошибочного утверждения внутри замыкания.
1) SuTTest :: testSuT
Ожидание не удалось для имени метода равно при вызове 1 раз (а)
Не удалось утверждать, что две строки равны.
--- Ожидаемый
+++ Фактический
@@ @@
-'hi '
+ 'нет'
Надеюсь, это поможет любому, кто сталкивается с подобной проблемой.