测试一个 class 方法调用另一个
Testing that one class method calls another
假设我有以下 class.
class SomeClass {
public function shortcutMethod($arg1) {
return $this->method($arg1, 'something');
}
public function method($arg1, $arg2) {
// some stuff
}
}
所以 shortcutMethod
是另一种方法的捷径。假设我想编写一个测试,给定 $arg1
shortcutMethod
将使用正确的参数正确调用 method
。
到目前为止,我认为我需要模拟 class 以期望使用一些参数调用 method
,然后像这样在模拟对象上调用 shortcutMethod
(注意我正在使用 Mockery)。
$mock = m::mock("SomeClass");
$mock = $mock->shouldReceive('method')->times(1)->withArgs([
'foo',
'something'
]);
$mock->shortcutMethod('foo');
这会导致像这样的异常 shortcutMethod() does not exist on this mock object
。
我是不是误解了 mocking 的用法?我知道对于依赖注入到 class 的对象更有意义,但在这种情况下呢?你会怎么做?也许更重要的是,这种测试是否无用,如果是,为什么?
您应该使用模拟来模拟被测 class 的 dependencies,而不是被测 class 本身。毕竟,您正在尝试测试 class.
的真实行为
你的例子有点基础。如何测试这样的 class 取决于 method
函数的作用。如果它 returns 一个值又由 shortCutMethod
返回,那么我会说你应该只是断言 shortCutMethod
的输出。 method
函数中的任何依赖项都应该被模拟(属于其他 classes 的方法)。我不太熟悉嘲弄,但我已经对你的示例进行了调整。
class SomeClass {
private $dependency;
public function __construct($mockedObject) {
$this->dependency = $mockedObject;
}
public function shortcutMethod($arg1) {
return $this->method($arg1, 'something');
}
public function method($arg1, $arg2) {
return $this->dependency->mockedMethod($arg1, $arg2);
}
}
$mock = m::mock("mockedClass");
$mock->shouldReceive('mockedMethod')->times(1)->withArgs([
'foo',
'something'
])->andReturn('returnedValue');
$testCase = new SomeClass($mock);
$this->assertEquals(
'returnedValue',
$testCase->shortcutMethod('foo')
);
话虽如此,可以部分模拟您的 class 被测,以便您可以测试 shortCutMethod
函数的真实行为,但模拟 method
函数以断言它是用预期的参数调用的。看看部分模拟。
http://docs.mockery.io/en/latest/reference/partial_mocks.html
假设我有以下 class.
class SomeClass {
public function shortcutMethod($arg1) {
return $this->method($arg1, 'something');
}
public function method($arg1, $arg2) {
// some stuff
}
}
所以 shortcutMethod
是另一种方法的捷径。假设我想编写一个测试,给定 $arg1
shortcutMethod
将使用正确的参数正确调用 method
。
到目前为止,我认为我需要模拟 class 以期望使用一些参数调用 method
,然后像这样在模拟对象上调用 shortcutMethod
(注意我正在使用 Mockery)。
$mock = m::mock("SomeClass");
$mock = $mock->shouldReceive('method')->times(1)->withArgs([
'foo',
'something'
]);
$mock->shortcutMethod('foo');
这会导致像这样的异常 shortcutMethod() does not exist on this mock object
。
我是不是误解了 mocking 的用法?我知道对于依赖注入到 class 的对象更有意义,但在这种情况下呢?你会怎么做?也许更重要的是,这种测试是否无用,如果是,为什么?
您应该使用模拟来模拟被测 class 的 dependencies,而不是被测 class 本身。毕竟,您正在尝试测试 class.
的真实行为你的例子有点基础。如何测试这样的 class 取决于 method
函数的作用。如果它 returns 一个值又由 shortCutMethod
返回,那么我会说你应该只是断言 shortCutMethod
的输出。 method
函数中的任何依赖项都应该被模拟(属于其他 classes 的方法)。我不太熟悉嘲弄,但我已经对你的示例进行了调整。
class SomeClass {
private $dependency;
public function __construct($mockedObject) {
$this->dependency = $mockedObject;
}
public function shortcutMethod($arg1) {
return $this->method($arg1, 'something');
}
public function method($arg1, $arg2) {
return $this->dependency->mockedMethod($arg1, $arg2);
}
}
$mock = m::mock("mockedClass");
$mock->shouldReceive('mockedMethod')->times(1)->withArgs([
'foo',
'something'
])->andReturn('returnedValue');
$testCase = new SomeClass($mock);
$this->assertEquals(
'returnedValue',
$testCase->shortcutMethod('foo')
);
话虽如此,可以部分模拟您的 class 被测,以便您可以测试 shortCutMethod
函数的真实行为,但模拟 method
函数以断言它是用预期的参数调用的。看看部分模拟。
http://docs.mockery.io/en/latest/reference/partial_mocks.html