在进行TDD时要模拟哪些对象

Jam*_*xon 9 tdd unit-testing mocking

在创建方法时,是否应该将在该方法中实例化的每个对象作为参数传入,以便可以在单元测试中模拟这些对象?

我们在工作中有很多方法,没有相关的单元测试,也没有回顾性地编写测试; 我们发现在这些方法中实例化了很多对象.

我们的一个选择是将我们当前的方法重构为更像单元的方法,并减少每个方法的责任数量.这可能是一个漫长的过程,但对我们来说肯定是一个很大的好处.

你怎么看?是否应将在方法中实例化的所有对象作为参数传入?

Mar*_*ann 7

也许不是所有的物体,但是你注入你的单位的物体越多,关注点的分离就越好,所以我肯定会建议你向这个方向移动.

您不必将所有对象作为方法参数传递.通过构造函数注入将协作者注入类中通常是更好的设计.这可以使您的界面保持干净,同时您的实施可以导入所需的协作者.

假设你的原始实现看起来像这样:

public class Foo
{
    public Ploeh DoStuff(Fnaah f)
    {
        var bar = new Bar();
        return bar.DoIt(f);
    }
}
Run Code Online (Sandbox Code Playgroud)

这可以改为看起来像这样:

public class Foo
{
    private readonly IBar bar;

    public Foo(IBar bar)
    {
        this.bar = bar;
    }

    public Ploeh DoStuff(Fnaah f)
    {
        return this.bar.DoIt(f);
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,我bar从Bar的实例更改为IBar的实例,从而将Foo与IBar的特定实现分离.这样的重构往往会使您的单元测试更易于编写和维护,因为您现在可以独立地改变Foo和Bar的实现.


Phi*_*eck 6

第一部分是一个有点问题.这就像问"当我的车里的行人跑过来时,我应该把双手放在方向盘上吗?"

实例化大量其他对象的方法几乎肯定做得太多了.具有大量这些方法的类可能不遵循单一责任原则.

但是,使代码可测试的关键方法之一是使用IoC(控制反转),其中将类的依赖(或方法)传递给它,而不是要求它们的类.这样可以更容易测试,因为你可以传入模拟.

所以简短的回答是"是",传入你的依赖关系并查看一个好的依赖注入组件.长的答案是"是的,但不要这样做".DI框架可能会强制您将依赖项传递给对象而不是方法,并且您会发现您希望确保限制这些依赖项 - 这是一件好事.

当然,重构以减少依赖性是好的.缩短你做一件事的方法几乎从来都不是坏事.我非常同意这是一个长期收益,只要你能负担短期费用.