Reputation: 381
I'm writing a unit test and i have 1 mock object that will return a dynamic type which has JSON in it. The call is async and looks to be fine, however when i run the code and step into class im testing, the mock is null (m.GetResults) and the return data i set isnt shown.
Im new to using Moq and not sure if I've done something wrong. Can anyone spot any issue for why it would be null?
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
class under test
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;
}
}
Upvotes: 3
Views: 6897
Reputation: 247088
You have already figured out that the setup of the mock was not matching the actual behavior to the expected behavior and that using the It.IsAny<T>()
was the solution for that problem like
mock.Setup(_ => _.GetResults(It.IsAny<string>(), It.IsAny<object>()))
.ReturnsAsync(json);
The resulting problem, based on the class under test and the set up of the mock is that it appears you are double serializing the expected JSON result. You manually create a JSON string and then serialize that again.
Consider refactoring the test to something a little simpler that generates the JSON using an actual object instead of try to craft it manually. The same object can be used for making assertions as well.
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);
}
Upvotes: 1