I have been asked to unit test the following controller in xunit using moq (C# .Net Core app 3.1):
private readonly IConfigService _configService;
private readonly IOptions<ApiVersion> _apiVersionSettings;
private readonly IOptions<MinRequiredDatabaseVersion> _minRequiredDatabaseVersion;
public InfoController(IConfigService configService, IOptions<ApiVersion> apiVersionSettings, IOptions<MinRequiredDatabaseVersion> minRequiredDatabaseVersion)
{
_configService = configService;
_apiVersionSettings = apiVersionSettings;
_minRequiredDatabaseVersion = minRequiredDatabaseVersion;
}
[HttpGet]
[ProducesResponseType(typeof(ApplicationVersionDto), 200)]
[ProducesResponseType(typeof(BadRequestResult), 400)]
public IActionResult GetVersions()
{
// get db version
var dbVersion = _configService.GetDbVersions();
// get api version
var apiVersion = _apiVersionSettings.Value.Version;
var minReqiredDbVersion = new MinRequiredDataVersion(_minRequiredDatabaseVersion.Value.Major, _minRequiredDatabaseVersion.Value.Minor, _minRequiredDatabaseVersion.Value.BuildNumber);
var isDatabaseRightVersion = _configService.hasWebSolutionTheRightDatabase(dbVersion, minReqiredDbVersion);
string currentDbVersion = dbVersion.MajorVersion + "." + dbVersion.MinorVersion + "." + dbVersion.BuildNumber;
string minDbVersion = minReqiredDbVersion.MajorVersion + "." + minReqiredDbVersion.MinorVersion + "." + minReqiredDbVersion.BuildNumber;
if (!isDatabaseRightVersion)
throw new CustomGisException(CustomGisExceptionName.ArgumentException, 202011101419083007, $"Update the database! current database version {currentDbVersion}, but should have been min. {minDbVersion}", $"Update the database! current database version {currentDbVersion}, but should have been min. {minDbVersion}");
var result = new ApplicationVersionDto(dbVersion, apiVersion);
return Json(result);
}
After setting up the mocks, the mocked Database Version service (_minRequiredDatabaseVersion) returns the default boolean value false even though the mock is set to return true, indicating that something is pear shaped:
[Fact]
public void GetVersionsGet_ReturnsJsonResult_WhenInvoked()
{
// Arrange
var mockVwCurrentVersionInfo = Mock.Of<VwCurrentVersionInfo>(x => x.BuildNumber == 988 && x.MajorVersion == 988 && x.MinorVersion == 988);
fixture.mockApiVersion.SetupGet(o => o.Value).Returns(new ApiVersion(){});
fixture.mockMinRequiredDatabaseVersion.SetupGet(o => o.Value).Returns(new MinRequiredDatabaseVersion(){
Major=888,
Minor=888,
BuildNumber=888});
fixture.mockConfigService.Setup(x => x.GetDbVersions()).Returns(mockVwCurrentVersionInfo);
fixture.mockConfigService.Setup(x => x.hasWebSolutionTheRightDatabase(mockVwCurrentVersionInfo, fixture.mockMinRequiredDataVersion.Object)).Returns(true);
// Act
var result = fixture.controller.GetVersions();
var jsonResult = result as JsonResult;
// Assert
// Assertions here.
}
When debugging I reach the line if(!isDatabaseRightVersion) in the controller, which throws the exception.
How can I return the boolean true in this mocked service?
Here is my fixture:
public InfoController controller;
public Mock<IConfigService> mockConfigService;
public Mock<IOptions<ApiVersion>> mockApiVersion;
public Mock<IOptions<MinRequiredDatabaseVersion>> mockMinRequiredDatabaseVersion;
public Mock<VwCurrentVersionInfo> mockVwCurrentVersionInfo;
public Mock<MinRequiredDataVersion> mockMinRequiredDataVersion;
public int vurderingsejendomIdToBeFound;
public InfoFixture()
{
// Mock services and their setups.
mockConfigService = new Mock<IConfigService>();
mockApiVersion = new Mock<IOptions<ApiVersion>>();
mockMinRequiredDatabaseVersion = new Mock<IOptions<MinRequiredDatabaseVersion>>();
mockVwCurrentVersionInfo = new Mock<VwCurrentVersionInfo>();
mockMinRequiredDataVersion = new Mock<MinRequiredDataVersion>();
mockMinRequiredDataVersion.Object.MajorVersion = 5;
mockMinRequiredDataVersion.Object.MinorVersion = 5;
mockMinRequiredDataVersion.Object.BuildNumber = 5;
// Controller
controller = new InfoController(mockConfigService.Object, mockApiVersion.Object, mockMinRequiredDatabaseVersion.Object);
}
public void Dispose() {}
Thanks in advance for your valuable feedback.
In your setup
fixture.mockConfigService
.Setup(x => x.hasWebSolutionTheRightDatabase(mockVwCurrentVersionInfo, fixture.mockMinRequiredDataVersion.Object))
.Returns(true);
fixture.mockMinRequiredDataVersion.Object
is not equal to minReqiredDbVersion
As an option you can use It.IsAny<T>
instead of fixture.mockMinRequiredDataVersion.Object
:
fixture.mockConfigService
.Setup(x => x.hasWebSolutionTheRightDatabase(mockVwCurrentVersionInfo,It.IsAny< MinRequiredDataVersion >() ))
.Returns(true);
This way you mock will work for any instance of MinRequiredDataVersion
I you need to make sure that minReqiredDbVersion has specific version, you can capture that parameter with callback:
MinRequiredDatabaseVersion capturedMinReqiredDbVersion = null;
fixture.mockConfigService
.Setup(x => x.hasWebSolutionTheRightDatabase(mockVwCurrentVersionInfo,It.IsAny< MinRequiredDataVersion >() ))
.Callback( (dbVersion, minReqiredDbVersion) => {capturedMinReqiredDbVersion = minReqiredDbVersion; })
.Returns(true);
// Assert
// Assert capturedMinReqiredDbVersion here