我的代码库(遗留)中有一个函数,它有:
function test()
{
method1("#input a")
method2("test")
method3(1,2)
}
鉴于它调用其他methods
的事实,如何为这些函数编写一个好的单元测试?
答案 0 :(得分:4)
首先,我认为你描述的这种行为甚至不需要进行单元测试。 但是,如果您确实需要检查是否使用特定参数(甚至任何参数)调用方法。 有一种方法可以做到这一点,你可以使用像ShortifyPunit这样的模拟框架: https://github.com/danrevah/ShortifyPunit
请按照以下步骤操作:
例如,如果您的类正在使用依赖注入,这对于单元测试至关重要,如下面的类:
class SomeClass {
private $obj;
public function __construct($obj) {
$this->obj = $obj;
}
public function test()
{
$this->obj->method1("#input a")
$this->obj->method2("test")
$this->obj->method3(1,2)
}
}
您可以按如下方式编写单元测试:
public function testMethodCalled()
{
$mockedObj = ShortifyPunit::mock('object');
$class = new SomeClass($mockedObj);
// Stub the methods so you could verify they were called
ShortifyPunit::when($mockedObj)->method1(anything())->returns(1);
ShortifyPunit::when($mockedObj)->method2(anything())->returns(2);
ShortifyPunit::when($mockedObj)->method3(anything(), anything())->returns(3);
$class->test(); // run test() method
// Verify it was called
$this->assertTrue(ShortifyPunit::verify($mockedObj)->method1(anything())->calledTimes(1));
$this->assertTrue(ShortifyPunit::verify($mockedObj)->method2(anything())->calledTimes(1));
$this->assertTrue(ShortifyPunit::verify($mockedObj)->method3(anything(), anything())->calledTimes(1));
}
答案 1 :(得分:2)
鉴于它调用其他
methods
(...)
它所谓的并不重要。从消费者(来电者)的角度来看,最终结果很重要。你总是测试最终结果。调用其他一些方法的事实是无关的实现细节(在大多数情况下)。
我建议简单的练习 - 内联method1
,method2
和method3
机构进入test
方法。您是否在确定要测试的内容时遇到问题?
您想要测试公共合同或可观察行为 - 方法调用的最终结果对于调用它的人是可见的(许多不同的actor可能会调用您的方法 - 程序的其他部分,单元测试或系统用户;每个应该体验相同的可观察行为)。
现在,回到"最终结果" /"方法的可观察行为"多次提到过。它可以是三件事之一:
您需要确定最终结果并对其进行测试。
答案 2 :(得分:0)
这是一个非常好的问题,我很长时间都在努力解决这个问题。在您的情况下,您有一个要测试的函数grid_col
,但该函数具有依赖项 - test
。
基本上有两种方式 -
method1-3
函数。示例 -
test
第二种方法可以让你灵活地模拟方法1,2和& 3。
它也可以是第一种情况和第二种情况的混合,其中一些方法直接从全局范围使用,一些方法作为参数传递。
现在唯一的问题是了解何时使用什么。以下是一些提示 -
适用于第一种情况
function test(method1, method2, method3) {
method1("#input a")
method2("test")
method3(1,2)
}
函数。对于所有其他情况,您可能希望将依赖项作为参数传递。例如 - 在这种情况下,它看起来像test
和method1
正在做一些DOM操作,这意味着它们应该注入并模拟method2
看起来非常简单的地方,并且可以从全球范围。
method3
如果依赖项变得太多,您可以传递包含所有依赖项的对象。