如何断言模拟对象的函数调用的对象参数
假设
class Foo {
public $att;
public function __construct ( $a ) { $this->att = $a; }
}
class Some {
public function callMe ( Foo $f ) {}
}
// class I want to test
class SuT {
public function testMe ( Some $s ) {
echo $s->callMe( new Foo('hi') );
}
}
我想检查 Sut::testMe()
是否正确调用 Some::callMe()
。由于参数是一个 (Foo
) 对象(不是标量类型),我不知道如何调用 PHPUnit 的 with()
来对其运行断言。例如,有一个 assertAttributeEquals
方法,但如何向其提供调用的参数?
我想做的是这样的:
class SuTTest extends PHPUnit_Framework_TestCase {
public function testSuT () {
$stub = $this->getMock( 'Some' );
$stub->expects( $this->once() )->method( 'callMe' )
->with( $this->assertAttributeEquals('hi', 'att', $this->argument(0) );
/*
* Will $stub->callMe be called with a Foo object whose $att is 'hi'?
*/
$sut = new SuT();
$sut->testMe( $stub );
}
}
Consider
class Foo {
public $att;
public function __construct ( $a ) { $this->att = $a; }
}
class Some {
public function callMe ( Foo $f ) {}
}
// class I want to test
class SuT {
public function testMe ( Some $s ) {
echo $s->callMe( new Foo('hi') );
}
}
I want to check whether Sut::testMe()
properly invokes Some::callMe()
. Since the parameter is a (Foo
) object (not a scalar type), I can't figure out how to call PHPUnit's with()
to run assertions on it. There is an assertAttributeEquals
method for example, but how do I feed it the invocation's argument?
What I'd like to do is this:
class SuTTest extends PHPUnit_Framework_TestCase {
public function testSuT () {
$stub = $this->getMock( 'Some' );
$stub->expects( $this->once() )->method( 'callMe' )
->with( $this->assertAttributeEquals('hi', 'att', $this->argument(0) );
/*
* Will $stub->callMe be called with a Foo object whose $att is 'hi'?
*/
$sut = new SuT();
$sut->testMe( $stub );
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
尽管问题已经得到充分解答(如何断言作为参数传递给模拟的对象的属性),但我认为值得注意的是 PHPUnit 支持传递给 with() 的回调约束。
当我试图找出如何对模拟对象参数运行进一步的断言时,我不断地碰到这个线程。例如,我需要检查某个方法的返回值。显然,为了理智起见,没有与上面答案中使用的属性断言等效的 methodReturnValueEqualTo() 。
幸运的是,PHPUnit 确实支持(至少从 3.7 开始)回调约束,这很有意义,您可以在专门的 Mock 库中找到它,例如 嘲讽。
当前 PHPUnit 版本文档< /a> 声明以下内容:
因此,使用回调约束,OP 示例现在可以表示为:
测试失败将类似于:
您现在可以对该论证运行任何逻辑。
更好的是,尽管 PHPUnit 文档中没有记录功能,但您实际上可以使用断言并获得断言错误消息的好处:
真的不知道这种使用断言并返回 true 的策略如何面向未来 >。它没有记录在案,并且错误消息中存在权衡。您不再收到参数约束消息,因此如果您对多个参数设置断言,您将必须推断(如果可能)哪一个参数失败了。但您确实可以更好地描述闭包内失败的断言。
希望这可以帮助任何面临类似问题的人。
Even though the question is already answered fully (how to assert attribute of object passed as argument to mock) I think it's worth noting that PHPUnit supports a callback constraint to be passed to with().
I kept bumping with this thread while trying to find out how to run further assertions on the mocked object arguments. For instance, I needed to check the return value of some method. Obviously, and for sanity sake, there is no methodReturnValueEqualTo() equivalent to the attribute assertion used in the answer above.
Fortunately, PHPUnit does support (as of 3.7 at least) a callback constraint, which makes a lot of sense and is something you can find in specialised Mock libraries like Mockery.
Current PHPUnit version docs state the following:
Therefore, using the callback constraint, the OP example can now be expressed as:
And a test fail would look something like:
You can now run any logic on that argument.
Even better, despite not being a documented feature in PHPUnit docs, you can actually use assertions and get the benefits of assertion error messages:
Don't really know how future proof is this strategy of using assertions and returning true. It is not documented and there is a tradeoff in the error message. You no longer get the parameter constraint message, so if you set assertions on multiple arguments you will have to infer, if possible, which one failed. But you do get a better description of the failed assertion inside the closure.
Hope this helps anyone facing a similar problem.
您只需将预期值传递给“with”方法即可。
您还可以传递一系列 phpUnit 断言而不是参数(默认等于)
因此对于对象您可以使用
$this->isInstanceOf("stdClass")
作为->with
的参数有关可能的断言列表,请查看:
PHPUnit/Framework/Assert.php
用于返回
new PHPUnit_Framework_Constraint
的函数小演示
第一个测试用例仅匹配 2 个参数并有效
第二个匹配两个参数并在参数 2 上失败
最后一个测试传入的对象是否为
stdClass
类型结果:
You just pass the expected values to the "with" method.
you can also pass in a range of phpUnit assertions instead of the parameters (it defaults to equal to)
so for objects you would use
$this->isInstanceOf("stdClass")
as a parameter to->with
For the list of possible assertions look into:
PHPUnit/Framework/Assert.php
for functions that return a
new PHPUnit_Framework_Constraint
Small Demo
The first testcase just matches 2 arguments and works
The second one matches two and fails on argument 2
The last one tests that the passed in object is of type
stdClass
Results in:
这是一个简单的示例,可以满足您的需要:
其余代码:
我希望对您有所帮助
This is a simple example that does what you need:
And the rest of code:
I hope that I've helped you