【问题标题】:How to test repository insertions?如何测试存储库插入?
【发布时间】:2014-10-07 09:45:45
【问题描述】:

我不确定如何测试将插入某些内容的存储库,应该将它们单独放置还是以某种方式进行测试?如果是,那么如何?我需要在存储库和上下文之间再增加一层吗?

使我的示例更加复杂的是,我正在使用 NoSQL 并且使我的数据士气低落,因此在保存时更改了两个实体,而不是一个。

示例模型

public class User
{
    public ObjectId Id { get; set; }
    public string Email { get; set; }
    // ... more properties
    public List<UserUsergroupDto> Usergroups { get; set; } // Usergroup Id and Name
}

public class Usergroup
{
    public ObjectId Id { get; set; }
    public string Name { get; set; }
    // ... more properties
    public List<UsergroupUserDto> Users { get; set; } // User Id and Email
}

示例存储库

public class UserRepository : IUserRepository
{
    // Inject db context, etc..        

    public User ChangeEmailById(ObjectId id, string email)
    {
        // Save user email
        var user = _db.Users.AsQueryable().First(x => x.Id == id);
        user.Email = email;
        _db.User.Save(user);

        // Save user email on every group he is (because denormalization)
        user.Usergroups.ForEach(x =>
        {
            var usergroup = _db.Usergroups.First(z => z.Id == x.Id);
            var userDto = usergroup.Users.First(z => z.Id == user.Id);
            userDto.Email = email;

            _db.Usergroups.Save(usergroup);
        };

        return user;
    }
}

问题

如何测试这样的存储库?如果它不可测试,那我该如何重构它呢?

【问题讨论】:

  • 我使用 dbcontext 工厂类来创建我的上下文并将其传递到我的存储库中。然后我可以使用 Moq 创建一个假的 contextfactory 或只是一个假的上下文,然后我可以测试 repo 是否在上下文中调用了正确的东西......如果这有意义

标签: c# repository tdd repository-pattern denormalization


【解决方案1】:

我相信您需要集成测试,而不是单元测试。通过集成测试,您可以测试您的 UserRepository 是否与实际的持久层正确配合(我还建议添加前缀 UserRepository 以使这种依赖关系更清晰,例如 MongoUserRepository 或您正在使用的任何底层 NoSQL DB) .

这些集成测试应该如下所示(我不懂 C#,因此为错误道歉)

public void testChangeUserEmailById() {
    /* setup */
    user          = nextUser(); /* using the unique generator pattern */
    expectedEmail = nextEmailAddress();
    dbSpy         = connectToTheActualNoSqlDb();
    dbSpy.insert(user);

    /* exercise */
    noSqlUserRepository.ChangeEmailById(user.id, expectedEmail);

    /* verify */
    assertEquals(expectedEmail, dbSpy.getUserEmail(user.id);
}

public void testChangeUserGroupsEmailById() {
    /* setup */
    user          = nextUser(); /* using the unique generator pattern */
    expectedEmail = nextEmailAddress();
    dbSpy         = connectToTheActualNoSqlDb();
    dbSpy.insert(user);

    /* exercise */
    noSqlUserRepository.ChangeEmailById(user.id, expectedEmail);

    /* verify */
    /* --- I've not really understood what is to be changed here --- */
}

最后,您可能需要将单元测试与集成测试分开,因为后者运行速度较慢。理想情况下,您的构建系统的默认任务应该只运行单元测试。然后,特定任务可以运行集成测试。显然你的持续集成系统同时运行

【讨论】:

    猜你喜欢
    • 2014-06-19
    • 2019-01-29
    • 1970-01-01
    • 2016-07-28
    • 2013-01-20
    • 1970-01-01
    • 2016-09-28
    • 2021-12-21
    • 1970-01-01
    相关资源
    最近更新 更多