使用.net核心对mongoDb进行单元测试

beq87vna  于 2022-11-19  发布在  .NET
关注(0)|答案(2)|浏览(173)

bounty将在5天后过期。回答此问题可获得+50的声望奖励。J.SMTBCJ15正在寻找标准答案:应能提供工作代码示例

我正在尝试为我的仓库写单元测试,这个仓库与MongoDb交互,但是在模拟对象时遇到了一个问题/异常。
这就是我的类的样子,也就是说,我创建了一个仓库类,并从接口扩展了它;

public class UserManagementRepository : IUserManagementRepository
{
    private readonly IMongoCollection<UserModel> _users;
    public UserManagementRepository(IDatabaseSettings dbSettings, IApplicationSettings applicationSettings, IMongoClient mongoClient)
    {
        IMongoDatabase database = mongoClient.GetDatabase(dbSettings.DatabaseName);
        _users = database.GetCollection<UserModel>(applicationSettings.UserCollectionName);
    }
    
    public async Task<GeneralResponse> Get(string id)
    {
        GeneralResponse response = new GeneralResponse();
        try
        {
            IAsyncCursor<UserModel> userModel = await _users.FindAsync(user => user.Id == id);
            if (userModel != null)
            {
                response.Message = "User exists!";
                response.Data = userModel.FirstOrDefault();
                response.ResponseCode = ResponseCode.Success;
            }
            else
            {
                response.Message = $"User with Id: {id} not found!";
                response.ResponseCode = ResponseCode.Success;
            }
        }
        catch (Exception ex)
        {
            response.Message = "Failure";
            response.ResponseCode = ResponseCode.Error;
        }
        return response;
    }
}

这是我的测试类的样子

public class UserManagmentRepositoryTests
{
    private Mock<IDatabaseSettings> _mockDbSettings;
    private Mock<IApplicationSettings> _mockApplicationSettings;
    private Mock<IMongoClient> _mockClient;
    public UserManagmentRepositoryTests()
    {
        _mockDbSettings = new Mock<IDatabaseSettings>();
        _mockApplicationSettings = new Mock<IApplicationSettings>();
        _mockClient = new Mock<IMongoClient>();
    }

    [Fact]
    public async Task GetUserWithId_Test()
    {
        // Arrange
        var repo = new Mock<IUserManagementRepository>();
        IDatabaseSettings dbSettings = new DatabaseSettings()
        {
            ConnectionString = "mongodb:connectionstring",
            DatabaseName = "dbname"
        };
        _mockDbSettings.Setup(x => x).Returns(dbSettings);

        IApplicationSettings applicationSettings = new ApplicationSettings() { UserCollectionName = "users" };
        _mockApplicationSettings.Setup(app => applicationSettings).Returns(applicationSettings);

        MongoClientSettings clientSettings = MongoClientSettings.FromConnectionString(dbSettings.ConnectionString);
        MongoClient client = new MongoClient(clientSettings);
        _mockClient.Setup(c => client);

        var ctr = new UserManagementRepository(_mockDbSettings.Object, _mockApplicationSettings.Object, _mockClient.Object);

        // Act
        var result = ctr.Get("132");

        // Assert
        //result.StatusCode.Should().NotBeNull();
    }
}

每次设置都出现异常

lbsnaicq

lbsnaicq1#

您正尝试使用ApplicationSettings作为表达式。setup方法要求您提供一个表达式,以确定何时激活模拟覆盖。
在本例中,只需完全删除Mock<IApplicationSettings>,并模拟需要调用其上的任何方法的所有对象:

[Fact]
public async Task GetUserWithId_Test()
{
  // Arrange
  var userModel = new UserModel() { Id = "123" };

  var mockCursor = new Mock<IAsyncCursor<UserModel>>();
  mockCursor
    .Setup(c => c.FirstOrDefault())
    .Returns(userModel);

  var mockCollection = new Mock<IMongoCollection<UserModel>>();
  Predicate<UserModel> filter = u => u.Id == userModel.Id;
  mockCollection
    .Setup(c => c.FindAsync(filter))
    .ReturnsAsync(mockCursor.Object);

  var mockDb = new Mock<IMongoDatabase>();
  mockDb
    .Setup(db => db.GetCollection<UserModel>(It.IsAny<string>()))
    .Returns(mockCollection.Object);

  _mockClient
    .Setup(c => c.GetDatabase(It.IsAny<string>()))
    .Returns(mockDb.Object)

  var ctr = new UserManagementRepository(new(), new(), _mockClient.Object);

  // Act
  var result = ctr.Get("132");

  // Assert
  result.StatusCode.Should().Be(ResponseCode.Success);
  result.Message.Should().Be("User exists!");
  result.Data.Should().Be(userModel);
}

希望这能帮上点忙🙂

5uzkadbs

5uzkadbs2#

若要将ApplicationSettings用作模拟的ApplicationSettings,必须在setup方法中使用表达式。
而不是:

IApplicationSettings applicationSettings = new ApplicationSettings() { UserCollectionName = "users" };
    _mockApplicationSettings.Setup(app => applicationSettings).Returns(applicationSettings);

例如,使用以下内容:

IApplicationSettings applicationSettings = new ApplicationSettings() { UserCollectionName= "users" };
    _mockApplicationSettings.Setup(app => app.UserCollectionName).Returns(applicationSettings.UserCollectionName);

编辑:完成示例

private Mock<IDatabaseSettings> _mockDbSettings;
    private Mock<IApplicationSettings> _mockApplicationSettings;
    private Mock<IMongoClient> _mockClient;
    public UserManagmentRepositoryTests()
    {
        _mockDbSettings = new Mock<IDatabaseSettings>();
        _mockApplicationSettings = new Mock<IApplicationSettings>();
        _mockClient = new Mock<IMongoClient>();
    }

    [Fact]
    public async Task GetUserWithId_Test()
    {
        // Arrange
        var repo = new Mock<IUserManagementRepository>();
        IDatabaseSettings dbSettings = new DatabaseSettings()
        {
            ConnectionString = "mongodb:connection",
            DatabaseName = "dbname"
        };
        _mockDbSettings.Setup(x => x.ConnectionString).Returns(dbSettings.ConnectionString);
        _mockDbSettings.Setup(x => x.DatabaseName).Returns(dbSettings.DatabaseName);

        IApplicationSettings applicationSettings = new ApplicationSettings() { UserCollectionName = "users" };
        _mockApplicationSettings.Setup(app => app.UserCollectionName).Returns(applicationSettings.UserCollectionName);

        MongoClientSettings clientSettings = MongoClientSettings.FromConnectionString(dbSettings.ConnectionString);
        MongoClient client = new MongoClient(clientSettings);
        _mockClient.Setup(c => c.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>()))
                    .Returns <string, MongoDatabaseSettings>((name, settings) => client.GetDatabase(name, settings));

        var ctr = new UserManagementRepository(_mockDbSettings.Object, _mockApplicationSettings.Object, _mockClient.Object);

        // Act
        var result = await ctr.Get("132");

        // Assert
        result.ResponseCode.Should().NotBe(ResponseCode.Error);
    }

相关问题