简体   繁体   English

使用Moq进行交互单元测试

[英]interaction unit testing using Moq

I have a testing class 我有一个测试班

    public class TerminationRequestValidation : ValidatorBase<TerminationRequest>
{
    public TerminationRequestValidation(IIntHR2BLLContext context) : base(context)
    {
    }

    public override ValidationResult ValidateWithoutThrow(TerminationRequest request)
    {
        var result = ValidationResult.Success;

        /* some logic */

        var isHRIAdvanced = Context.Logics.Accessible.HasAccess(request, IntHRSecurityOperationCode.TerminationRequestSetTerminationDateBehindhand);

        if (!isHRIAdvanced && Context.Logics.Termination.IsTerminationDateChanged(request))
        {
            result += CheckTerminationDate(request);                
        }

        return result;
    }

    public virtual ValidationResult CheckTerminationDate(TerminationRequest request)
    {
        var result = ValidationResult.Success;

        /* any validation logic */

        return result;
    }
}

I need to check 'CheckTerminationDate' method is performed 我需要检查“ CheckTerminationDate”方法是否已执行

        [TestMethod]
    public void Validate_TerminationDateChangedbyNotAdvanced_TerminationDateCheck()
    {
        var context = FakeContext.Create();
        // first stub
        var accessibleBllStub = new Mock<IAccessibleBLL>(MockBehavior.Loose);

        accessibleBllStub.Setup(z => z.HasAccess(It.IsAny<TerminationRequest>(), It.IsAny<IntHRSecurityOperationCode>()))

            .Returns<TerminationRequest, IntHRSecurityOperationCode>((x, y) => y != IntHRSecurityOperationCode.TerminationRequestSetTerminationDateBehindhand);

        context.StubBLL(z => z.Accessible, accessibleBllStub.Object);
        // second stub
        var terminationBLLStub = new Mock<ITerminationBLL>(MockBehavior.Loose);

        terminationBLLStub.Setup(z => z.IsTerminationDateChanged(It.IsAny<TerminationRequest>())).Returns(true);

        context.StubBLL(z => z.Termination, terminationBLLStub.Object);
        // mock
        var validator = new Mock<TerminationRequestValidation>(MockBehavior.Loose, context.MainContext);
        // act
        validator.Object.ValidateWithoutThrow(termination);
        //assert
        validator.Verify(z => z.CheckTerminationDate(It.IsAny<TerminationRequest>()));
    }

This unit test off course isn't work. 当然,此单元测试不起作用。 On the one hand I need to call real 'ValidateWithoutThrow' method, on the another hand I need to check that stub method 'CheckTerminationDate' is performed. 一方面,我需要调用真正的“ ValidateWithoutThrow”方法,另一方面,我需要检查是否执行了存根方法“ CheckTerminationDate”。

Guys, help me to find the best solution! 伙计们,帮我找到最好的解决方案! May be I need to redesign testing class to make in more testable 可能我需要重新设计测试课程以使测试更容易

I need to check 'CheckTerminationDate' method is performed 我需要检查“ CheckTerminationDate”方法是否已执行

You don't. 你不知道 You need to test that the request was validated. 您需要测试该request已验证。 Whether that's done inline, or by calling CheckTerminationDate , or by calling some other method, that's an implementation detail - and unit tests don't care about that. 无论是内联完成,还是通过调用CheckTerminationDate ,或通过其他方法,这都是实现细节-单元测试并不关心这一点。

So, your tests should look something like this: 因此,您的测试应如下所示:

public void ValidateWithoutThrow_ReturnsSucessfulResult_When_RequestIsValid() 
{
    var validRequest = //...
    var validator = new TerminationRequestValidation(/*...*/); // don't mock this class

    var result = validator.TerminationRequestValidation(validRequest);

    Assert.Equal(ValidationResult.Success, result);
}

public void ValidateWithoutThrow_ReturnsUnsucessfulResult_When_RequestIsInvalid() 
{
    var invalidRequest = //...
    var validator = new TerminationRequestValidation(/*...*/); // don't mock this class

    var result = validator.TerminationRequestValidation(invalidRequest);

    Assert.NotEqual(ValidationResult.Success, result);
}

As a general rule of thumb, avoid verifying how the method works internally. 作为一般经验法则,请避免验证该方法在内部如何工作。 You're coupling your tests to implementation details and refactoring/maintaining those details will be a living hell. 您正在将测试与实现细节耦合,并且重构/维护这些细节将是一个活生生的麻烦。

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

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