Below is InvokeAsync method which need to tested.
public async Task<bool> InvokeAsync(Batch batch)
{
var refundRequests = await this.RefundRepository.GetsAsync(batch.RefundRequests.Select(x => x.Id));
refundRequests.RemoveAll(x => x.Status != RefundRequestStatus.Approved);
var distributions = await DistributionRepository.GetsAsync(refundRequests.Select(x => x.Distribution.Id));
var bundles = await this.BundleRepository.GetsAsync(distributions.Select(x => x.BundleId));
foreach (var getRefundRequest in refundRequests)
{
var distribution = distributions.FirstOrDefault(x => x.Id == getRefundRequest.Distribution.Id);
if (distribution?.BundleId != null)
{
var bundle = bundles.First(x => x.Id == distribution?.BundleId);
Bundle result = await Reverse.InvokeAsync(getRefundRequest, distribution, bundle); //MOCK
}
getRefundRequest.Status = RefundRequestStatus.Closed;
getRefundRequest.LastUpdatedBy = "Test User";
bool isUpdated = await UpdateRefund.InvokeAsync(getRefundRequest); //MOCK
}
batch.Status = BatchStatus.Posted;
batch.LastUpdatedBy = "Test User";
var isSuccess = await UpdateBatch.InvokeAsync(batch); //MOCK
return isSuccess;
}
Unit test method
[Fact]
public async Task Post_Batch()
{
foreach (var refundBatch in Factory.Batch.CreateRefundBatchesData())
{
var refundRequests = await this.RefundRequestRepository.GetsAsync(batch.RefundRequests.Select(x => x.Id));
var distributions = await this.DistributionRepository.GetsAsync(refundRequests.Select(x => x.Distribution.Id));
var bundles = await this.BundleRepository.GetsAsync(distributions.Select(x => x.BundleId));
for (int i = 0; i < refundRequests.Count; i )
{
var refundRequest = refundRequests[i];
var bundle = bundles[i];
var distribution = distributions[i];
MockSetupReverse(refundRequest, distribution, bundle);
MockSetupUpdateRefund(refundRequest);
}
MockSetupUpdateBatch(batch);
//Act
var postRefund = await UseCase.InvokeAsync(batch);
//Assert
postRefund.ShouldNotBeNull();
postRefund.IsPosted.ShouldBeTrue();
}
}
MockSetup methods
private void MockSetupReverse(RefundRequest refundRequest, Distribution distribution, Bundle bundle)
{
this.MockReverse
.Setup(x => x.InvokeAsync(refundRequest, distribution, bundle))
.Returns(async () =>
{
bundle.Status = BundleStatus.Closed;
return await Task.Run(() => bundle);
});
}
private void MockSetupUpdateRefund(RefundRequest refundRequest)
{
this.MockUpdateRefund
.Setup(x => x.InvokeAsync(refundRequest))
.Returns(async () =>
{
refundRequest.Status = RefundRequestStatus.Closed;
refundRequest.LastUpdatedBy = Factory.RefundRequest.TestUserName;
return await Task.Run(() => true);
});
}
private void MockSetupUpdateBatch(Batch batch)
{
this.MockUpdateBatch
.Setup(x => x.InvokeAsync(batch))
.Returns(async () =>
{
refundBatch.Status = BatchStatus.Posted;
refundBatch.LastUpdatedBy = Factory.RefundRequest.TestUserName;
return await Task.Run(() => true);
});
}
The mocking of the UpdateBatch is working and returns true when the method is invoked. But, the mocking of the Reverse and UpdateRefund returns false when the respective method is invoked. Any thoughts?
Please let me know if more info is required to support the question.
CodePudding user response:
When you Setup
your mocks with a specific parameter, the Returns
only applies when this specific parameter is used.
The reason UpdateBatch
works is because you're using the same reference to the same Batch
in both the mock and the class under test:
MockSetupUpdateBatch(batch);
//Act
var postRefund = await UseCase.InvokeAsync(batch); // <---- Same "batch"
When your test code is calling RefundRequestRepository.GetsAsync
you probably get different results than when the tested class calls GetsAsync
, so the setup is not relevant for the calls of the tested class and probably returns the default bool value (false
).
For more information on how to mock correctly refer to this GitHub page