【问题标题】:Mock a Class in a Class in a Unit Test在单元测试的类中模拟一个类
【发布时间】:2017-05-12 02:47:57
【问题描述】:

我在单元测试中有以下代码

using Moq;
using OtherClass;
[TestClass]
public class TestClass
{
    [TestMethod]
    public void TestMethod()
    {
        OtherClass other = new OtherClass();
        OtherClass.foo();
    }
}

这是另一个类

using ThirdClass;
public class OtherClass
{
    public void foo()
    {
        ThirdClass third = new ThirdClass();
        third.bar();
    }
}

ThirdClass 仍在开发中,但我希望能够使用 moq 运行我的单元测试。有没有办法告诉 moq 在 TestClass 中模拟 ThirdClass 而不让 OtherClass 使用/依赖于 moq?理想情况下是这样的:

public void TestMethod()
{
    OtherClass other = new OtherClass();
    Mock<ThirdClass> third =  new Mock<ThirdClass>();
    third.setup(o => o.bar()).Returns(/*mock implementation*/);
    /*use third in all instances of ThirdClass in OtherClass*/
    OtherClass.foo();
}

【问题讨论】:

  • 听起来像OtherClass 应该提供ThirdClass 的一个实例,而不是创建一个。

标签: c# unit-testing mocking moq


【解决方案1】:

OtherClass 类中的方法 foo() 不可单元测试,因为您创建了真实服务的新实例并且无法模拟它。

如果你想模拟它,那么你必须用依赖注入注入ThirdClass

OtherClass 的示例将是:

public class OtherClass
{
    private readonly ThirdClass _thirdClass;
    public OtherClass(ThirdClass thirdClass) 
    {
         _thirdClass = thirdClass;
    }
    public void foo()
    {
        _thirdClass.bar();
    }
}

您的测试方法以及测试其他类的示例可以是:

public void TestMethod()
{
    // Arrange
    Mock<ThirdClass> third =  new Mock<ThirdClass>();
    third.setup(o => o.bar()).Returns(/*mock implementation*/);

    OtherClass testObject= new OtherClass(third);

    // Action
    testObject.foo();

    // Assert
    ///TODO: Add some assertion.
}

您可以使用Unity DI 容器的示例尝试。

【讨论】:

  • 在实现接口时应该做Mock&lt;InterfaceName&gt; third = new Mock&lt;InterfaceName&gt;();
  • @DevendraLattu 根据Moq 模拟类型可以是“接口、类或委托”。无论如何,在他的示例中没有接口。
【解决方案2】:

谢谢你的想法,伙计们。我最终制作了另一个版本的 OtherClass.foo() ,它接受了 ThirdClass 的实例,并且在没有它的版本中创建了一个实例。测试时我可以调用 foo(mockThird),但用户可以只使用 foo()。

using ThirdClass;
public class OtherClass
{
    public void foo(ThirdClass third)
    {
        third.bar();
    }
    public void foo()
    {
        foo(new ThirdClass());
    }
}

在测试类中

public void TestMethod()
{
    Mock<ThirdClass> third =  new Mock<ThirdClass>();
    third.setup(o => o.bar()).Returns(/*mock implementation*/);
    OtherClass testObject= new OtherClass();

    testObject.foo(third);
}

【讨论】:

  • 我只想让您知道,根据本门户的规定,您不能发布其他问题作为答案。如果有必要,您必须编辑原始问题或添加为 cmets。如果您编辑问题,请确保与答案保持一致。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-14
  • 1970-01-01
  • 2015-05-05
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多