使用多个构造函数参数模拟和测试类

时间:2011-02-21 04:19:12

标签: unit-testing nunit mocking moq

我的服务层类是为构造函数注入而设置的。在模拟和测试这些类时,如何避免在null中传入我在测试中不会使用的参数?

我试图避免的示例代码:

[TestFixture]
public class SomeServicesTests
{
    SomeServices _someServices;

    [SetUp]
    public void Initialize()
    {
        _someServices= new SomeServices (null, 
                                        new StubRepositoryOne(), 
                                        null, 
                                        null, 
                                        new StubRepositoryTwo(), 
                                        null, 
                                        null, 
                                        null,
                                        null);

    }

    [Test]
    public void Test_Something()
    {
        string input = "yes";
        string exptectedOutput = "no";

        string output = _someServices.SomeFunction(input); // uses StubRepositoryOne and StubRepositoryTwo
        Assert.AreEqual(exptectedOutput, output);
    }
}

3 个答案:

答案 0 :(得分:3)

在我的答案被接受后添加我的答案,但是......

事实上,只有一些依赖项需要传入测试,这表明存在可能的设计问题。一个好的试金石是一个类型中的所有字段都应该用在每个方法中 - 很难一直这样做 - 但是如果你不能这样做意味着这个类可能会被分成更小的类,责任更细。当你将它们分解时,每个类只会占用它们需要的依赖项。

另一方面,如果您在这里所做的是手动服务定位器而您只测试功能的子集,则可能需要考虑创建仅测试构造函数。如:

internal SomeServices(IServiceOne one, IServiceTwo two)
{
}

或者使用getter / setter公开服务并相应地进行分配。同样,这里的internal关键字可用于保持您的设计意图清洁:

public IServiceOne One
{
   get { return _one; }
   internal set { _one = value; }
}

当然,您需要将InternalsVisibleTo属性添加到代码中,以允许您的测试访问这些内部方法。

答案 1 :(得分:2)

我通常验证注入的参数与null。我通常只是传入

new Mock<T>().Object

这些。

答案 2 :(得分:2)

存根所有缺少的参数,并始终检查SomeService中的空args。每次使用它时检查输入是否繁琐是很麻烦的。因此,最好总是在构造函数中检查null,并抛出ArgumentNullException。

你提到一些输入参数是私有的。它们必须被提取,以使您的注射模式起作用。