【发布时间】:2019-08-24 09:07:29
【问题描述】:
上下文
我正在为我一直在开发的 API 编写单元测试,但在尝试对访问 MongoDB 存储的“上下文”进行单元测试时遇到了一个问题。
我为我的上下文抽象了当前接口:
public interface IProjectsContext
{
IMongoCollection<Project> Projects { get; }
}
我能够成功地使用这个接口,连同Moq 对我的存储库进行单元测试。
但是,在尝试对我的 Context 的实现进行单元测试时,我无法找到一个模拟内部的解决方案:
public class ProjectsContext : IProjectsContext
{
private const string ProjectsCollectionName = "Projects";
private readonly IDatabaseParameters _dbParams;
private readonly MongoClient _client;
private readonly IMongoDatabase _database;
private IMongoCollection<Project> _projects;
public ProjectsContext(IDatabaseParameters dbParams)
{
_dbParams = dbParams ?? throw new ArgumentNullException(nameof(dbParams));
_client = new MongoClient(_dbParams.ConnectionString);
_database = _client.GetDatabase(_dbParams.DatabaseName);
}
public IMongoCollection<Project> Projects
{
get
{
if (_projects is null)
_projects = _database.GetCollection<Project>(ProjectsCollectionName);
return _projects;
}
}
}
有问题的单元测试是:
private readonly Fixture _fixture = new Fixture();
private readonly Mock<IDatabaseParameters> _dbParametersMock = new Mock<IDatabaseParameters>();
public ProjectsContextTests()
{
}
[Fact(DisplayName = "Create a Project Context")]
public void CreateProjectContext()
{
// Arrange
_dbParametersMock.Setup(m => m.ConnectionString).Returns(_fixture.Create<string>());
_dbParametersMock.Setup(m => m.DatabaseName).Returns(_fixture.Create<string>());
// Act
var result = new ProjectsContext(_dbParametersMock.Object);
// Assert
result.Should().NotBeNull();
result.Should().BeAssignableTo<IProjectsContext>();
// TODO: Write a test to assert the ProjectCollection
}
问题
我能想到的唯一解决方案是将我的ProjectsContext 更改为具有接收作为参数的构造函数,IMongoDatabase 将被使用。然而,这是唯一的解决方案吗?
使用的库
我正在为我的单元测试和实现使用以下 NuGet:
- xUnit
- Coverlet.msbuild
- 起订量
- 自动夹具
- FluentAssertions
- MongoDB
【问题讨论】:
-
MongoClient是你创建的类吗? -
MongoClient 由 MongoDB.Driver 为 CSharp 提供
-
@AlvesRC 您的
ProjectsContext与实现问题MongoClient紧密耦合,这使得对其进行隔离测试变得困难。IMongoDatabase是真正的依赖,应该显式注入到目标类中。 -
@Nkosi 这就是我的想法,尽管我希望可能有更好的方法哈哈。您能否发布一个答案,以便我将其选为正确答案?
-
@AlvesRC 这是一种更可靠的方法。
标签: c# mongodb unit-testing asp.net-core