AutoMoqer:将参数传递给构造函数

时间:2011-12-06 20:44:51

标签: c# unit-testing c#-4.0 mocking moq

当我需要模拟一些类似这样的课程时:

public class Dummy
{
  private readonly int _someInt;
  private readonly int _someOtherInt;
  private readonly IFoo _foo;

    public Dummy(int someInt,int someOtherInt, IFoo foo)
    {
      _someInt = someInt;
      _someOtherInt = someOtherInt;
      _foo = foo;
    }
}

我使用Moq做这样的事情:

[Test]
public void ShouldCreateADummyInstance()
{
      var someInt = 1;
      var someOtherInt = 2;

      var mockFoo = new Mock<IFoo>();

      var dummy = new Dummy(someInt, someOtherInt, mockFoo.Object);

      //And so on...
}

但是当我使用AutoMoq时,我无法为构造函数中的每个依赖项(我的意思是someInt和someOtherInt)指定不同的int,因为AutoMoqer.SetInstace(instanceIWantToUse)每次必须设置相同的指定实例供给那种依赖。

你知道我如何为someInt和someOtherInt指定一个不同的int,以便在我的测试中继续使用AutoMoqer?

谢谢,希望你能帮助我!

2 个答案:

答案 0 :(得分:2)

完全披露:我从来没有使用过AutoMoq(虽然我只是注册在GitHub上关注它,因为它看起来很有趣并且我喜欢减少样板的东西)。

也就是说,看起来AutoMoq工具是针对不同用例而设计的。如果添加了另一个构造函数注入依赖项,并且能够为依赖项生成一个默认对象,可能会使用它来“破坏单元测试的未来证明”,可能是为了避免空引用异常。

我会在阅读AutoMoq项目页面后假设,如果Darren正在编写您的特定单元测试,他可能只是使用Moq开箱即用。也就是说,对于那个特定的测试,你应该选择你发布的测试。当您不想在测试中指定所有依赖项时,AutoMoq似乎旨在提供合理的默认行为。但在您的情况下,您想要指定这些特定的依赖项。

仅仅因为您使用常规Moq进行特定测试并不意味着您无法将AutoMoq用于其他测试。其余的测试(其中两个整数都是零或其他)将是面向未来的,但是如果你在Dummy类中添加另一个构造函数参数,你可能只需要使用那个测试。

(您也可以随时获取AutoMoq的源代码并根据需要进行修改。)

答案 1 :(得分:0)

类似于Moq的解决方案

您可以在AutoMoq中创建Dummy的实例,就像在Moq中创建实例一样。 这不会在将来证明您的测试代码不受构造函数参数的更改,但仍然可以接受。

var mocker = new AutoMoqer();
var fooMock = mocker.GetMock<IFoo>();
var dummy = new Dummy(1, 2, fooMock.Object);
// test something about dummy

AutoMoq解决方案

如果您真的想将来验证您的TestCode,则可能有必要更改构造函数以依赖于接口。

interface IDummyParameters {
    int SomeInt {get;set;}
    int SomeOtherInt {get;set;}
}

public class Dummy {
    public Dummy(IDummyParameters parameters, IFoo foo){
        ...
    }
}

然后您可以使用AutoMoq创建您的Dummy类,如下所示:

var mocker = new AutoMoqer();
mocker.GetMock<IDummyParameters>.Setup(x => x.SomeInt).Returns(1);
mocker.GetMock<IDummyParameters>.Setup(x => x.SomeOtherInt).Returns(2);
// notice how this code does not say anything about IFoo.
// It is created automatically by AutoMoq
var dummy = mocker.Create<Dummy>();