所有 Moq 测试用例都通过而不检查任何逻辑?

All Moq testCases pass without checking any logic?

我正在学习这个 intro to unit testing 教程。

我没有实施逻辑来确定应该 return "Maybe"、"Declined" 的信用评分,但是 Moq 测试通过了所有单元测试。

public interface ICreditDecisionService {
    string GetCreditDecision(int creditScore);
}

public class CreditDecision {
ICreditDecisionService creditDecisionService;

public CreditDecision(ICreditDecisionService creditDecisionService) {
    this.creditDecisionService = creditDecisionService;
}

public string MakeCreditDecision(int creditScore) {
    return creditDecisionService.GetCreditDecision(creditScore);
}

===================================
// Testing Class
[TestFixture]
public class CreditDecisionTests {
    //mock instance for dependency
    Mock < ICreditDecisionService > mockCreditDecisionService;

    CreditDecision systemUnderTest;

    [TestCase(100, "Declined")]
    [TestCase(549, "Declined")]
    [TestCase(550, "Maybe")]
    [TestCase(674, "Maybe")]
    [TestCase(675, "We look forward to doing business with you!")]
    public void MakeCreditDecision_Always_ReturnsExpectedResult(int creditScore, string expectedResult) {

        //Arrange
        //creating and configuring the mock 
        mockCreditDecisionService = new Mock < ICreditDecisionService > (MockBehavior.Strict);
        mockCreditDecisionService.Setup(p => p.GetCreditDecision(creditScore)).Returns(expectedResult);

        systemUnderTest = new CreditDecision(mockCreditDecisionService.Object);
        var result = systemUnderTest.MakeCreditDecision(creditScore);

        Assert.That(result, Is.EqualTo(expectedResult));

        mockCreditDecisionService.VerifyAll();
    }
}

我没有 ICreditDecisionService 的实现,但是 Moq 测试通过了!你能解释一下这些代码有什么问题吗?

据我所知,您的代码与 designed/written 完全一样。您正在创建 ICreditDecisionService 的模拟,并告诉它在每种情况下要 return 做什么。另一方面,测试断言发生了两件事:

  1. CreditDecision.MakeCreditDecision() returns 由 ICreditDecisionService 生成的值(在这种情况下模拟为始终 return 一个 correct/known 值).

  2. 调用 CreditDecision.MakeCreditDecision() 使用正确的值 creditScore 调用 ICreditDecisionService.GetCreditDecision()

因此,您的测试是测试 CreditDecision 而不是 ICreditDecisionService。您不需要 ICreditDecisionService 的实现来测试 CreditDecision;这就是模拟的用武之地。您将 CreditDecisionICreditDecisionService 隔离开来,无论实际实现是什么,以便仅测试 CreditDecision.

但是,我会更改测试名称以反映测试中真正发生的事情;也许像 MakeCreditDecision_Returns_Result_From_Service 这样的描述会更好。