Search code examples
c#unit-testingmoqmoq-3

All Moq testCases pass without checking any logic?


I am following this intro to unit testing tutorial.

I have not implemented a logic to determine what credit score should return "Maybe", "Declined" but Moq test passes all the Unit Tests.

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();
    }
}

I don't have implementation of ICreditDecisionService, yet Moq test passess! Could you explain what is wrong with these codes.


Solution

  • As far as I can tell, your code is working exactly as designed/written. You're creating a mock of ICreditDecisionService and telling it what to return in each case. The test on the other hand is asserting two things happen:

    1. CreditDecision.MakeCreditDecision() returns the value generated by the ICreditDecisionService (in this case mocked to always return a correct/known value).

    2. Calling CreditDecision.MakeCreditDecision() calls ICreditDecisionService.GetCreditDecision() with the correct value of creditScore.

    Therefore, your test is testing CreditDecision not ICreditDecisionService. You do not need an implementation of ICreditDecisionService to test CreditDecision; this is where the mock comes in. You're isolating CreditDecision from ICreditDecisionService, whatever the actual implementation might be, in order to test only CreditDecision.

    I would, however, change the test name to reflect what's really happening in the test; perhaps something like MakeCreditDecision_Returns_Result_From_Service would be a better description.