我的服务层类是为构造函数注入而设置的。在模拟和测试这些类时,如何避免在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);
}
}
答案 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。
你提到一些输入参数是私有的。它们必须被提取,以使您的注射模式起作用。