简体   繁体   中英

C# moq how to correctly setup an interface to return a desired value

I've writing various tests for my app and now I got to a problem that I'm unable to solve. The test I'm writing is a simple command that executes and action that modifies a database and then a query to validate that the values are correct. In order to connect to the database my BaseContext gets the connection string from an interface:

        public BaseContext(DbContextOptions options, IConnectionStringProvider connectionStringProvider)
            : base(options)
        {
            _connectionStringProvider   = connectionStringProvider;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                var connString =_connectionStringProvider.GetConnectionString();
                optionsBuilder.UseOracle(connString);
            }
        }

My connection string provider interface looks like this:

    public interface IConnectionStringProvider
    {
        string GetConnectionString();
        Dictionary<string, string> GetConnectionSession();
    }

And the implementation looks like this:


    public class HttpConnectionStringProvider : IConnectionStringProvider
    {
        public HttpConnectionStringProvider(IConfiguration configuration, IHttpContextAccessor httpContextAccessor)
        {
            _configuration = configuration ?? throw new NullReferenceException(nameof(configuration));
            _httpContext = httpContextAccessor.HttpContext ?? throw new NullReferenceException("HttpContext");
        }

        public string GetConnectionString()
        {
            // Do something with http context and configuration file and return connection string
        }

    }

All this interfaces are registered using autofac.

Then when executing the following test:


        [Test]
        public async Task AddProductTest()
        {

            string connectionString = "fixed_connection_string";

            var mock = new MockRepository(MockBehavior.Default);

            var mockConnectionStringProvider = new Mock<IConnectionStringProvider>();
            mockConnectionStringProvider.Setup(x => x.GetConnectionString())
                .Returns(connectionString);


            await ProductModule.ExecuteCommandAsync(new AddProductCommand(1, "nameProduct"));

            var products = await ProdcutModule.ExecuteQueryAsync(new GetProducts(1));
            // Assert
            Assert.That(products .Status, Is.EqualTo(ResultQueryStatus.Ok));
            Assert.That(products .Value, Is.Not.Empty);
            Assert.That(products .Value.Any(x => x.Name== "nameProduct"));
        }

The IConfiguration and IHttpContextAccessor are mocked using NSubstitute library. But even if I deleted them just to test if IConnectionStringProvider returned the value expected in setup it didn't work.

When running the test in debug I see that steps into the method GetConnectionString() when it should be mocked. I don't know what I'm doing wrong I suppose there is something that I don't understand about testing.

I am curious what you are attempting to do:

Mocking out the connection string for creating someone like a DB connection string or similar, doesn't make a lot of sense. It is part of the base functionality of the DI bits for C# service handling in Setup.

if you want to mess with this, of course you can do it, but the purpose escapes me a bit.

However, if you simply wish to test ProductModule as something you have written, then it makes more sense.

Then when you make this statement:

ProductModule productModule = new ProductModule( - parameters - ); your parameters likely requires a IConnectionStringProvider.

There you need to use your mockConnectionStringProvider.Object

That will allow you to insert your mocked object, as the object used in your ProductModule constructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM