【问题标题】:Integration test instead of unit test集成测试而不是单元测试
【发布时间】:2016-11-08 06:33:19
【问题描述】:

假设我有一个自定义集合对象。如何为 remove 方法创建单元测试(没有依赖项)?我必须先调用 add 方法,然后才能删除该项目,因此 remove 方法依赖于 add 方法。在大多数情况下,此自定义集合类将具有一个受保护的属性,其中包括所有添加的集合项。因此我无法模拟 add 方法,因为那时我没有要删除的集合项。

class Item 
{
    private $identifier;

    public function __construct($identifier)
    {
        $this->identifier = $identifier;
    }

    public function getIdentifier() { return $this->identifier; }
    ...
}

class customCollection
{
    protected $items = [];  
    public function add($item) {
        $this->items[$item->getIdentifier()] = $item;
    }
    public function remove($item) {
        unset($this->items[$item->getIdentifier()]);
    }
    public function getItems()
    {
        return $this->items;
    }
}

我可以使用对象聚合并将集合项数组传递给构造函数,并将其用作此自定义集合对象的初始集合项,但如果 add 方法可能修改多个对象属性,这可能会出现问题。那么你将如何解决这个任务或者只是一个集成测试呢?感谢您的反馈!

【问题讨论】:

  • 进行单元测试假定大量使用模拟来替换依赖项。我不认为这个特殊情况有什么特别之处,因为不遵循这个提议。只需几行代码,您的测试就是安全的(以及您的生产代码)。

标签: php unit-testing phpunit


【解决方案1】:

如果Item 足够简单,请不要担心复杂性,集成测试就可以了。编写几个测试先测试Item,然后再测试customCollection。如果Item 测试运行正常而customCollection 测试失败,则该错误很可能在集合中。

如果Item 非常复杂,让它实现集合所需的接口,然后你可以用这个接口的简单实现来存根Item。然后分别测试Item 和普通实现,然后是普通实现的集合,然后还有Item 实现。 (但我怀疑这是否值得。)

分离单元测试和集成测试的重点在于轻松定位错误所在。但是,如果您仅通过结构良好的集成测试来达到同样的效果,那就没问题了。

【讨论】:

  • 感谢您的反馈。我关心的是集合的删除方法。我必须调用 add 函数来填充 items 属性,如果此方法出现故障,则 remove 测试也会失败,尽管它工作得非常好,并且失败只是因为 add 方法的实现中的错误而发生。
  • 我会同时测试这两种方法。首先add一些项目,然后检查它们是否正确插入,然后remove它们并再次检查。我看不出这有什么问题,也看不到任何其他选择。让测试变得太大和太复杂不是一个好主意,但事实并非如此——你有两个互补的动作,一起测试它们是有意义的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-07-13
  • 2021-12-19
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多