我不能让mock创建一个简单的假人:
<?php
require_once '../vendor/autoload.php'; // composer autoload mockery
class Foo {
private $required;
public function __construct($required){
$this->required = $required;
}
public function bar(){
// do stuff with $this->required
}
}
class FooTest extends PHPUnit_Framework_TestCase {
public function testBar(){
$mock = Mockery::mock('Foo');
$mock->bar();
}
}
运行PHPUnit测试给出错误:
BadMethodCallException: Method Mockery_0_Foo::bar() does not exist on this mock object
我做错了什么?
如果你想在"Foo"类和模拟"Required"对象上做php单元测试。就像下面这样做:
class Foo {
private $required;
public function __construct(Required $required){
$this->required = $required;
}
public function bar(){
return $this->required->getTextFromBarTable();
}
}
class FooTest extends PHPUnit_Framework_TestCase {
public function testBar(){
$mock = Mockery::mock('Required'); // Dummy, There are no properties or methods.
/**
* Stub "getTextFromBarTable" method of Required class
* and fakes response by returning "return this text".
*/
$mock->shouldReceive('getTextFromBarTable')
->andReturn('return this text');
// create "Foo" Object by using $mock instead of actual "Required" Object.
$foo = new Foo($mock);
$response = $foo->bar();
$this->assertEqual('return this text', $response);
}
}
你必须不要存根或模拟类,你想做单元测试。只需在"Required"之类的依赖类上执行即可。
我们使用STUB或MOCK来分离可能影响我们要测试的方法的内部逻辑的外部逻辑。在这种情况下,我假设Required类具有"getTextFromBarTable"方法,该方法将连接并从数据库中获取"文本"字段。如果我们的数据库没有文本字段,"testBar"方法将被破坏。为了摆脱外部问题,我在"Required"上做了存根,每次我都使用"getTextFromBarTable"方法。它总是会返回"return this text"
我必须显式地声明mock生成哪些方法的存根:
class FooTest extends PHPUnit_Framework_TestCase {
public function testBar(){
$mock = Mockery::mock('Foo');
$mock->shouldReceive('bar');
$mock->bar();
}
}
我很好奇是否有一种方法可以解决这个问题,或者:
- 隐式捕获
Foo
中定义的所有方法调用,或 - 隐式捕获所有方法调用,无论它们是否在
Foo
中定义。