Reputation: 323
I am writing unit tests using Moq in xUnit for a service that involves CosmosDB. There's a method GetVehicleInfo
which returns ItemResponse<VehicleInfo>
from CosmosDB. As ItemResponse
has a protected constructor so I can't new it up. Therefore, I'm mocking the caller method and doing
var responseMock = new Mock<ItemResponse<VehicleInfo>>();
responseMock.Setup(x => x.Resource).Returns(expectedItem); //expectedItem is of VehicleInfo type
cosmoRepoServiceStub.Setup(service => service.GetVehicleInfo("a1", "a2").Result).Returns(responseMock.Object);
The problem I face is that when GetVehicleInfo
is called as below, it returns null
always. I expect it to return ItemResponse<VehicleInfo>
wherein Resource
will contain expectedItem
.
ItemResponse<VehicleInfo> response = await _cosmosRepo.GetVehicleInfo(plate, country);
if (response == null){ //... }
Upvotes: 6
Views: 4201
Reputation: 22829
You should setup your cosmoRepoServiceStub like this:
cosmoRepoServiceStub
.Setup(service => service.GetVehicleInfo(It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync(responseMock.Object);
GetVehicleInfo
parameters should any string in the setup method.Result
inside the method selector please prefer ReturnsAsync
Or if you really need to anticipate "a1"
as a first argument then define it as
const StringComparison comparison = StringComparison.OrdinalIgnoreCase;
cosmoRepoServiceStub
.Setup(service => service.GetVehicleInfo(
It.Is<string>(param1 => string.Equals(param1, "a1", comparison),
It.Is<string>(param1 => string.Equals(param1, "a2", comparison)))
.ReturnsAsync(responseMock.Object);
UPDATE #1 Reflect to comment
Why does
It.IsAny
work whereas"a1"
does not?
Moq uses uses object.Equals
under the hood to check the Setup
's argument against the actual invocation's argument.
This means that the comparison for value types and for strings are based on their values (not based on their references).
So, in your particular case that means either plate
or country
does not contain a1
or a2
strings respectively.
In short I should work, but as a general rule of thumb
Setup
as generic as possibleVerify
as specific as possibleUpvotes: 6