繁体   English   中英

如何使用moq断言在C#中调用的函数?

[英]How do I use moq to assert a function is called in c#?

我正在尝试学习如何使用Moq用C#进行单元测试。 我设置了一个简单的类BasicMath,它具有一个函数int Multiply(int a, int b) ,主体仅返回a * b。 我还有另一个叫做AdvancedMath的类,它具有一个函数'int Square(int a)',主体调用Multiply(a,a)并返回结果。

我正在尝试为AdvancedMath.Square编写一个简单的测试,该测试将断言使用正确的值调用BasicMath.Multiply。 我知道您无法使用普通的公共功能执行此操作,因此我将功能虚拟化,但是仍然遇到麻烦。 有人可以向我解释如何完成吗? 除了默认的空构造函数,这两个类都没有其他构造函数。

这是我的尝试:

class test_Advanced_Functions
{
    [Test]
    public void test_SquareFunction_Should_return_correct_result()
    {
        // Arrange
        Mock<BasicFunctions> mock = new Mock<BasicFunctions>();
        AdvancedFunctions af = new AdvancedFunctions();

        // Act
        int result = af.Square(5);

        //Assert
        mock.Verify(d => d.Multiply(5, 5), Times.Exactly(1));
    }

假设AdvancedMathBasicMath派生的,那么当Multiply是虚拟的时,您可以使用Moq进行测试:

var mock = new Mock<AdvancedMath>();
mock.Setup(m => m.Multiply(2, 2)).Returns(4);
mock.Object.Square(2);
mock.VerifyAll();

如果您在AdvancedMath使用BasicMath (即,如果Multiply是静态的并且直接从Square调用),则无法使用Moq测试这种交互。 要了解原因,请参阅此问题

但是,在这种简单情况下进行基于行为的验证似乎并不正确。 您需要回答一个问题: “我要测试什么?” Square 起作用或调用了某些方法? 假设此测试有效,则此测试(您现在打算做的事情)仅将责任委托给Multiply 您的Square实现可能会以多种方式发生变化(例如,不使用Multiply ),它将破坏您的测试-不会。

Moq无法修改尚未创建的实例的行为。

您应该通过练习依赖注入来编写可进行单元测试的类。 由于AdvancedFunctions显然取决于BasicFunctions ,它应该有一个BasicFunctions传过来的构造函数的参数,而不是new ING一上来就其自身。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM