2

我正在尝试学习如何使用 Moq 使用 C# 进行单元测试。我设置了一个简单的类,BasicMath,它有一个函数int Multiply(int a, int b),主体只返回一个 * 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));
    }
4

2 回答 2

3

假设从那时AdvancedMath派生,您可以在虚拟BasicMath时使用 Moq 进行测试:Multiply

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

如果您使用BasicMathwithin AdvancedMath(即 ifMultiply是静态的并且直接从 调用),那么使用 MoqSquare测试这种交互是不可能的。要了解原因,请参阅此问题

但是,在这种简单的情况下进行基于行为的验证似乎并不正确。您需要回答自己一个问题:“我要测试什么?” . 那Square 行得通还是它调用了一些方法?这个测试(你现在计划做的),只将责任委托给Multiply,假设它有效。您的Square实现可能会以多种方式发生变化(例如,不使用Multiply),它会破坏您的测试 - 它不应该。

于 2012-05-07T15:55:56.403 回答
1

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

您应该通过练习依赖注入将您的类编写为可单元测试的。由于AdvancedFunctions显然依赖于BasicFunctions,它应该有一个BasicFunctions作为构造函数参数传入,而不是new单独设置一个。

于 2012-05-07T15:58:20.790 回答