Problem
I want to unit test a method in my repository class that checks if a record should be updated or created new. For some reason, the assertion keeps failing because the value is coming back false, when i'm expecting true. I can't see where I've gone wrong.
Code
I have the following repository class:
public class WidgetRepository()
{
public bool InsertOrUpdateWidget(Widget widgetToEval)
{
var retval = false;
var existingRecord = FindExistingWidget(widgetToEval);
if (existingRecord == null)
{
retval = InsertNewWidget(widgetToEval);
}
else
{
retval = UpdateExistingWidget(widgetToEval, existingRecord);
}
return retval;
}
Unit Test
[Fact]
public void Insert_New_Widget()
{
var repo = GetEmptyRepository();
var newWidget = new Widget()
{
ID = 1,
Name= "test",
Description= "Test widget",
};
var result = repo.InsertOrUpdateWidget(newWidget);
Assert.True(result);
}
private IWidgetRepository GetEmptyRepository()
{
var repo = new Mock<IWidgetRepository >();
repo.Setup(s => s.FindExistingWidget(It.IsAny<Widget>())).Returns((Widget)null);
repo.Setup(s => s.InsertNewWidget(It.IsAny<Widget>())).Returns(true);
return repo.Object;
}
In the unit test, I'm trying to mock the FindExistingWidget method and have it return a null object. I've also mocked the insert function and have it return a true. When I run this test, instead of returning a true, it returns false.
CodePudding user response:
When you want to test your repository you don't test the interface. You mock your repo when you want you want to test somehting using it. It's 'unit' test so you should test every method while it's sepereated from the others.
You should be testing WidgetRepository and not IWidgetRepository.
CodePudding user response:
If you are going to mock your repository and you just want it to return true, then do this;
private IWidgetRepository GetEmptyRepository()
{
var repo = new Mock<IWidgetRepository >();
repo.Setup(s => s.InsertOrUpdateWidget(It.IsAny<Widget>())).Returns(true);
return repo.Object;
}
You can't mock just a portion of the WidgetRepository class. In the instance you are using above is your mock, and based on your setup above, you did not implement the function you are calling (InsertOrUpdateWidget
) with repo.Setup
. Since it returns a boolean, it will default to the value false
. This function may be implemented in your concrete implementation of IWidgetRepository
, but it isn't in your mock. The return statement return repo.Object;
is not of WidgetRepository
, but of a mocked version of IWidgetRepository
. These are two different implementations, and only one of them implements InsertOrUpdateWidget
. It isn't the one you are testing.
CodePudding user response:
As the previous answers states, you are not Mocking the call to InsertOrUpdateWidget(), so its returning false (it's not even calling the code in the concrete class)