模拟对象在单元测试中为空

时间:2018-08-15 14:11:22

标签: c# unit-testing asp.net-core mocking moq

我正在编写一个单元测试,我有1个模拟对象,该对象将返回其中包含JSON的动态类型。调用是异步的,看起来还不错,但是当我运行代码并进入类即时测试时,模拟为null(m.GetResults),并且未显示我设置的返回数据。

我是使用Moq的新手,不确定我做错了什么。谁能发现任何问题,为什么会为空?

public async Task GetPaymentDetailSummaryTestAsync(){                        

    Task<dynamic> json = GetSampleJsonAsync();

    var mock = new Mock<ICallProcedure>();
    mock.Setup(m => m.GetResults("dbo.GetPaymentDetailSummary", 
                                 new { ID = 600002, Year = 2018})) 
                                .ReturnsAsync(json);            

    var payments = new Payments(mock.Object);
    var result = await payments.GetPaymentDetailSummaryAsync(2018, 600002);
    Assert.IsNotNull(result);
    Assert.IsInstanceOfType(result, typeof(List<PaymentSummary>));
    Assert.AreEqual(1, result.Count);
}

public async Task<dynamic> GetSampleJsonAsync(){            
    return await Task.FromResult(JsonConvert.SerializeObject("[{\"PaymentNumber\":1,\"Payment\":1200.00}]")); 
}

Payments被测类

public class Payments : IPayments
{
    private ICallProcedure callProc;

    public Payments(ICallProcedure CallProc)
    {
        callProc = CallProc;
    }

    public async Task<List<PaymentSummary>> GetPaymentDetailSummaryAsync(int year, int iD)
    {
        var getPaymentDetailSummary = await callProc.GetResults("dbo.GetPayment", new { ID = id, Year = year });
        List<PaymentSummary> paymentDetailSummary = null;
        paymentDetailSummary = JsonConvert.DeserializeObject<List<PaymentSummary>>(getPaymentDetailSummary);

        return paymentDetailSummary;
    }
}

1 个答案:

答案 0 :(得分:0)

您已经发现模拟程序的设置与实际行为与预期行为不匹配,并且使用It.IsAny<T>()是解决诸如此类问题的解决方案

mock.Setup(_ => _.GetResults(It.IsAny<string>(), It.IsAny<object>())) 
    .ReturnsAsync(json); 

基于被测类和模拟程序的设置,导致的问题是您似乎正在双重序列化预期的JSON结果。您手动创建一个JSON字符串,然后再次对其进行序列化。

考虑将测试重构为一个更简单的方法,该方法使用实际对象生成JSON,而不是尝试手工制作。同样的对象也可以用于声明。

public async Task GetPaymentDetailSummaryTestAsync(){                        
    //Arrange
    List<PaymentSummary> expected = new List<PaymentSummary> {
        new PaymentSummary {
            PaymentNumber = 1,
            Payment = 1200.00
        }
    };
    var json = JsonConvert.SerializeObject(expected);

    var mock = new Mock<ICallProcedure>();
    mock.Setup(_ => _.GetResults(It.IsAny<string>(), It.IsAny<object>())) 
        .ReturnsAsync(json);            

    var payments = new Payments(mock.Object);

    //Act
    var actual = await payments.GetPaymentDetailSummaryAsync(2018, 600002);

    //Assert
    Assert.IsNotNull(actual);
    Assert.IsInstanceOfType(actual, typeof(List<PaymentSummary>));
    Assert.AreEqual(1, actual.Count);
    CollectionAssert.AreEquivalent(expected, actual);
}