Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock GetConnectionString() from IConfiguration using moq?

Research: Mocking IConfiguration from .NET Core

I need to integration test my data access layer to ensure that all the code is working properly.

I know that it isn't going to work using the normal way:

//Will return a NotSupportedException
var mock = new Mock<IConfiguration>();
            mock.Setup(arg => arg.GetConnectionString(It.IsAny<string>()))
            .Returns("testDatabase");

Normally the data access layer uses dependency injection and it retrieves the connection string with IConfiguration.

My integration test:

[Fact]
public async void GetOrderById_ScenarioReturnsCorrectData_ReturnsTrue()
{
    // Arrange
    OrderDTO order = new OrderDTO();
    // Mocking the ASP.NET IConfiguration for getting the connection string from appsettings.json
    var mockConfSection = new Mock<IConfigurationSection>();
    mockConfSection.SetupGet(m => m[It.Is<string>(s => s == "testDB")]).Returns("mock value");

    var mockConfiguration = new Mock<IConfiguration>();
    mockConfiguration.Setup(a => a.GetSection(It.Is<string>(s => s == "ConnectionStrings:testDB"))).Returns(mockConfSection.Object);

    IDataAccess dataAccess = new SqlDatabase(mockConfiguration.Object);
    IRepository repository = new repository(dataAccess, connectionStringData);
    var connectionStringData = new ConnectionStringData
    {
        SqlConnectionLocation = "testDatabase"
    };
    
    // Act
    int id = await repository.CreateOrder(order);
 
    // Assert
    Assert.Equal(1, id);
}

But I get an error

System.InvalidOperationException: The ConnectionString property has not been initialized.

I'm a bit lost here, I'm not sure what happened.

like image 731
Coding-Is-An-Adventure Avatar asked Jun 21 '20 19:06

Coding-Is-An-Adventure


1 Answers

Try changing :

 mockConfiguration.Setup(a => a.GetSection(It.Is<string>(s => s == "ConnectionStrings:testDB"))).Returns(mockConfSection.Object);

To:

 mockConfiguration.Setup(a => a.GetSection(It.Is<string>(s => s == "ConnectionStrings"))).Returns(mockConfSection.Object);

Next setup prints "mock value":

var mockConfSection = new Mock<IConfigurationSection>();
mockConfSection.SetupGet(m => m[It.Is<string>(s => s == "testDB")]).Returns("mock value");

var mockConfiguration = new Mock<IConfiguration>();
mockConfiguration.Setup(a => a.GetSection(It.Is<string>(s => s == "ConnectionStrings"))).Returns(mockConfSection.Object);

Console.WriteLine(mockConfiguration.Object.GetConnectionString("testDB")); // prints "mock value"
like image 185
Guru Stron Avatar answered Sep 22 '22 12:09

Guru Stron