【问题标题】:Unit test with multiple interfaces具有多个接口的单元测试
【发布时间】:2018-05-21 20:47:50
【问题描述】:

我有一个从 API 控制器调用的具有以下服务类的 Web API 项目。我想使用 Moq 框架为下面的类编写单元测试用例。如何使用 Moq 构建多个接口?如果不能使用 Moq,还有其他框架吗?

public class MyService : IMyService
{
    private readonly IInterface1 _interface1;
    private readonly IInterfaces2 _interface2;
    private readonly IInterface3 _interface3;

    public MyService(IInterface1 interface1,IInterface2 interface2,IInterface3 interface3)
    {
        _interface1=interface1;
        _interface2=interface2;            
        _interface3=interface3;
    }

    public SomeModel MyMethod1(1Model model)
    {
        //do something here.... 
    }

    public SomeMode2 MyMethod2(Model2 model)
    {
        //do something here.... 
    }

    public SomeMode3 MyMethod3(Model3 model)
    {
        //do something here.... 
    }
}

【问题讨论】:

  • 只需为每个依赖项的接口构建一个 Mock 并将它们传递给您的 sut。
  • 模拟接口并将它们传递给被测类。除了参考 Moq Quickstart
  • 您必须创建 3 个模拟并将其注入构造函数中,这与大多数网站的玩具示例没有太大区别。

标签: c# unit-testing moq vs-unit-testing-framework


【解决方案1】:

想象一下你有这些接口:

public interface IOne
{
    int Foo();
}

public interface ITwo
{
    int Foo(string str);
}

你有一个依赖于上述接口的类:

public class Some
{
    private readonly IOne one;
    private readonly ITwo two;

    public Some(IOne one, ITwo two)
    {
        this.one = one;
        this.two = two;
    }

    public void Work()
    {
        // Uses one and two
    }
}

现在您想测试Work() 方法并想模拟依赖项,方法如下:

// Arrange
// Let's set up a mock for IOne so when Foo is called, it will return 5
var iOneMock = new Mock<IOne>();
iOneMock.Setup(x => x.Foo()).Returns(5);

// Let's set up the mock for ITwo when Foo is called with any string, 
// it will return 1
var iTwoMock = new Mock<ITwo>();
iTwoMock.Setup(x => x.Foo(It.IsAny<string>())).Returns(1);

var some = new Some(iOneMock.Object, iTwoMock.Object);

// Act
some.Work();

// Assert
// Let's verify iOneMock.Foo was called. 
iOneMock.Verify(x => x.Foo());
// Let's verify iTwoMock.Foo was called with string "One" and was called only once
iTwoMock.Verify(x => x.Foo("One"), Times.Once());

在我上面的例子中,我试图展示带参数的方法,不带参数的方法,调用验证方法和调用一次验证方法。这应该让您了解可用的选项。还有许多其他选项可用。有关更多信息,请参阅起订量文档。

【讨论】:

    【解决方案2】:

    你可以使用AutoMoq来解决依赖注入。

    var mocker = new AutoMoqer();
    var myService = mocker.Create<MyService>();
    var interface1 = mocker.GetMock<IInterface1>();
    

    【讨论】:

      猜你喜欢
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 2020-10-30
      • 1970-01-01
      • 2012-11-27
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      相关资源
      最近更新 更多