【问题标题】:How to test if method from one class, calls method from the other class using Moq?如何测试一个类的方法是否使用 Moq 调用另一个类的方法?
【发布时间】:2017-06-13 19:01:38
【问题描述】:
     public interface Interface1
     {
        void DoSomething1(int a);
     }

     public interface Interface2
     {
        void DoSomething2(int a);
     }

    public class Class1: Interface1
    {
        private Interface2 _interface2;

        public Class1(Interface2 _interface2)
        {
            this._inteface2= _interface2;
        }

        public void DoSomething1(int a)
        {
            _interface2.DoSomething2(a);
        }
    }

public class Class2: Interface2
    {
        public void DoSomething2(int a)
        {
            // some action
        }
    }

这是简化的代码。 我想知道如何在 C# 中的特定 TestCases 上测试 Class1 是否使用 Moq 从 Class2 调用 DoSomething2(int a)?

【问题讨论】:

  • minimal reproducible example 中显示您迄今为止尝试过的内容以及遇到困难的地方。这样一来,它表明在试图弄清楚它时需要付出一些努力,而不仅仅是向我展示如何去做。

标签: c# unit-testing moq


【解决方案1】:

如果你要测试 Class1,你应该模拟它的依赖,在这种情况下 Interface2 像这样

//First create the mock
var mocked = new Mock<Interface2>();

//then setup how the mocked interface methods should work
mocked.Setup(a=>a.DoSomething2(It.IsAny<int>()).Returns(null);

//Add the mocked object to the Class1 constructor
var class1 = new Class1(mocked.Object);

//then Act on your class1 which will use your mocked interface
class1.DoSomething1(1);

【讨论】:

  • 谢谢,问题出在安装程序中。我没用过“It.IsAny
  • @hurms 为什么将我的答案标记为正确然后又将其删除?我没有提供正确的解决方案吗?
  • 我不知道。我也只是点击了正确的另一个答案,然后它取消了我假设的你的。我的错。
  • @hurms 是的,每个问题只有一个正确答案。您可以根据自己的喜好为尽可能多的答案投票
【解决方案2】:

当您将 Interface2 注入到 Class1 构造函数时,您需要使用 Moq 模拟它。然后你需要执行 DoSomething1 并调用Verify 方法以确保Interface2 的方法被调用一次。如果不是 - 测试将失败。示例如下:

[TestFixture]
public class Class1Tests
{
    [Test]
    public void DoSomething1_DoSomething2IsCalled()
    {
        //Setup
        //create a mock for Class1 dependency 
        var mock = new Mock<Interface2>();
        var sut = new Class1(mock.Object);

        //execute
        sut.DoSomething1(It.IsAny<int>());

        //test
        mock.Verify(m => m.DoSomething2(It.IsAny<int>()), Times.Once());
    }
}

【讨论】:

  • 请尽量避免仅仅将代码作为答案,并尝试解释它的作用和原因。对于没有相关编码经验的人来说,您的代码可能并不明显。请编辑您的答案以包含clarification, context and try to mention any limitations, assumptions or simplifications in your answer.
  • 感谢@Sam Onela 的反馈。认为 cmets 应该足够了。会更新的
  • 我正在使用验证方法,现在我还有一个问题。如果我想用错误的参数对其进行测试,那么第二种方法永远不会被调用,我应该如何实现第一种方法?我已经实现了方法,所以如果参数错误它会抛出异常,所以当我运行单元测试时,它总是会抛出异常。它从来没有给我开绿灯,第二种方法没有被调用一次。使用 mocked.Verify(a => a.DoSomething2(a), Times.Never());谢谢你的回答。
  • 如果您期望抛出异常,我建议使用以下命令:Assert.Throws(() => { _sut.DoSomething(); })
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
  • 1970-01-01
  • 1970-01-01
  • 2020-05-28
  • 2021-03-12
相关资源
最近更新 更多