Reputation: 75
I am having an issue while testing one of the service method which uses an async Repository method.
public interface IRepo
{
Task<Model> GetByIdAsync(string Id);
Task SaveAsync(Model model);
}
void Process(string Id)
{
var model = _repo.GetByIdAsync(Id).Result;
model.Field1 = "update";
_repo.SaveAsync(model).Wait();
}
[Fact]
SUTServiceTest()
{
//Arrange
Model model = new Model();
var mockRepo = Mock.Get(new Repo());
mockRepo.Setup(x => x.GetByIdAsync(It.IsNotNull<string>()))
.Returns(() => Task.FromResult(model));
mockRepo.Setup(x => x.SaveAsync(It.IsAny<Model>()))
.Callback<Model>((obj) => model = obj);
var _service = new SUTService(mockRepo);
//Act
_service.Process("1");
//Assert
Assert.Equal("update", model.Field1);
}
I'm getting the following error at _repo.SaveAsync(model).await();
:
System.NullReferenceException - Object reference not set to an instance of an object
Not sure what did I miss.
Upvotes: 0
Views: 1151
Reputation: 22679
The intent behind this answer is to capture valuable information from the chat discussion.
As the OP said a NullReferenceException
has been thrown at the following line:
_repo.SaveAsync(model).Wait();
The _repo
tried to be initialized in the following way in the unit test:
var mockRepo = Mock.Get(new Repo());
That's not the correct way to do it. Please check the documentation of the Mock.Get
to know when it should be used and for what purpose.
The _repo
should be initialized in the following way:
var mockRepo = new Mock<IRepo>();
The OP had the following observation after changing the mock creation:
However, I loose the DI setup that I have for Repo construction
In short: That's the whole point.
Whenever you are unit testing a component then you try to mock out (simplify and mimic) all of its dependencies. It needs to rely on stubs and spies to be able to verify which one of them have been called under certain circumstances but the concrete implementation of the mocked objects do not matter.
In this particular case that means that the Service layer do not want to rely on a concrete Repository instance. It needs only a repo, which can capture the calling parameters and which can verify its calling.
FYI: Testing terminologies
Upvotes: 3