I have a controller method like this :
public class ValuesController : Controller
{
private readonly IService fService;
public ValuesController( IService fService)
{
this.fService = fService;
}
public IActionResult InsertDetails( [FromForm]Details details, IFormFile file)
{
bool result = fService.SaveDetails(details, file);
return OK();
}
}
The test case to test this controller is as below:
public class ValuesControllerTests
{
readonly Mock<IService> mockService = new Mock<IService>();
[TestMethod]
public void SaveDetails_Test_Success()
{
var details = GetMockDetails(); // gets the sample DTO values
mockService.Setup(x => x.SaveDetails(details, GetFile())).Returns(true); ---- this is returning false even after mocking the value
var controller = new ValuesController(mockService.Object);
controller.ControllerContext.HttpContext = new DefaultHttpContext();
var res = controller.InsertDetails(details, GetFile()) as OkObjectResult;
Assert.AreEqual("File Details Saved Successfully", res.Value.ToString());
Assert.AreEqual(200, res.StatusCode);
}
IFormFile GetFile()
{
return new FormFile(new MemoryStream(Encoding.UTF8.GetBytes("This is a dummy file")), 0, 0, "Data", "dummy.txt");
}
}
Even though I mocked the method SaveDetails to return true, it always returns false.
Can anyone tell me what am I doing wrong here? Many thanks.
The expectation was setup with a different
IFormFile(reference/instance) than the one that was used when invoking the member under test. This causes the mock to return the default value of the invoked member, which isfalsesince it is a boolean.When
GetFile()is invoked, it returns a new instance every time.So either use the same instance, like was done with
detailsOr loosen up the expectation using argument matchers like
It.IsAny<>()