I am now using Moq. I have a case where I am not sure what I am doing wrong and I hope you can guide me.
the code and the testing are:
public class MyLogic{
private readonly IRepository _repository;
public MyLogic(IRepository repository)
{
_repository = repository;
}
public async Task<Product> Create(Estimate estimate, Policy policy)
{
Product product = new Product(policy.Title, estimate.Id);
return await _repository.Create(product);
}
}
[Fact]
public Class MyLogicTest{
Mock<IRepository> _repository = new DBRepository();
MyLogic myLogic = new MyLogic(_repository);
Estimate _estimate = new Estimate(){
Id = Guid.Parse("5aa4d4a1-23e4-495b-b990-08da0d38e5df")
};
Policy _policy = new Policy(){
Title = "The Title"
};
public async Task CreateShouldBeDifferentFromNull(){
Product product = new Product()
{
Title = "The Title",
Id = Guid.Parse("5aa4d4a1-23e4-495b-b990-08da0d38e5df")
};
_repository.Setup(g => g.Create(product)).ReturnsAsync(() => product);
Product createdProduct = await myLogic.Create(_estimate, _policy);
Assert.NotNull(createdProduct);
Assert.Equal(product.Id, createdProduct.Id);
_repository.Verify(g => g.Create(product));
}
}
The Assert always fails because createdProduct is always null. And, I know I can change the class MyLogic to receive a Product instead of the two parameters. But what I want is to test the code as it is.
How can I make the mocked IRepository use the Product instance I declared in the test in order for the test to succeed?
CodePudding user response:
You need to setup the Create
method to return your wanted Product
when it receives an instance of the type Product
with some specific Title
and some specific Id
. Now you are setting up the Create
method to return your wanted Product
when it receives exactly that object you created. Which of course fails because that is completely another different object than the one created inside your Create
method.
So change your setup line to:
_productRepository.Setup(g => g.Create(It.Is<Product>(p => p.Id == product.Id && p.Title == product.Title)).ReturnsAsync(() => product);
Alternatively you can override Equals method and == operator and your original code will work as well.