【发布时间】:2021-06-28 05:11:46
【问题描述】:
我已经为我的应用编写了各种测试,但现在我遇到了一个我无法解决的问题。 我正在编写的测试是一个简单的命令,它执行和修改数据库的操作,然后是一个查询以验证值是否正确。 为了连接到数据库,我的 BaseContext 从接口获取连接字符串:
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);
}
}
我的连接字符串提供程序界面如下所示:
public interface IConnectionStringProvider
{
string GetConnectionString();
Dictionary<string, string> GetConnectionSession();
}
实现如下所示:
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
}
}
所有这些接口都是使用 autofac 注册的。
然后在执行以下测试时:
[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"));
}
使用 NSubstitute 库模拟 IConfiguration 和 IHttpContextAccessor。但即使我删除它们只是为了测试 IConnectionStringProvider 是否返回了设置中预期的值,它也不起作用。
在调试中运行测试时,我看到应该模拟 GetConnectionString() 方法的步骤。我不知道我做错了什么我想我对测试有些不理解。
【问题讨论】:
-
您创建
mockConnectionStringProvider。您实际在哪里使用它? -
命令 AddProduct 被分派时执行的命令处理程序使用 ProductRepository,而 ProductRepository 又使用使用 ConnectionStringProvider 的 BaseContext。还是您的意思是我必须将 mockConnectionStringProvider 实际传递给使用它的实际对象?那如果是使用依赖注入注册的怎么办呢?
-
在测试中,您应该模拟依赖项并将模拟依赖项注册或注入实际依赖项,以便使用这些依赖项的类将引用模拟。您的设计应遵循 SOLID 原则,这将使您的代码具有可测试性和可扩展性。
标签: c# unit-testing dependency-injection moq