如何避免持久化单元测试数据?

时间:2017-03-21 11:39:06

标签: .net unit-testing asp.net-core entity-framework-core

我有一个使用Entity Framework设置的ASP.NET核心(.NET Framework)项目,用于处理我的数据库。我在我的解决方案中创建了一个单独的测试项目。

我将如何为“注册”,“注册”等终端编写单元测试?

以下是我的RegisterUser端点的片段。

public async Task<IActionResult> RegisterUser(string email, string name, string password)
    {
        var user = new User { UserName = email, Email = email, Name = name };

        IdentityResult resultCreate = null;

        if (email.EndsWith("@stud.ntnu.no") || email.EndsWith("@ntnu.no"))
        {
            // Student or teacher?
            var role = (email.EndsWith("@stud.ntnu.no") ? "Student" : "Teacher");

            resultCreate = await _userManager.CreateAsync(user, password);
            if (resultCreate.Succeeded)
            {
                // Add role
                var resultRole = await _userManager.AddToRoleAsync(user, role);

                if (resultRole.Succeeded)
                {
                    // Sign in
                    await _signInManager.SignInAsync(user, true);

                    return Ok();
                }

            }
        }

        // Error
        return StatusCode(400, resultCreate?.Errors);
    }

1 个答案:

答案 0 :(得分:2)

根据原帖后面的评论判断,实际问题似乎是“如何避免持续存在单元测试数据?”

有很多方法可以解决这个问题:

核心,真实的书籍,教条式单元测试方式:

单元测试应该只测试一件事,其他一切都应该被模拟。因此,模仿您的_userManager_signInManager。由于它们被嘲笑,它们不会持久存在,因此避免测试数据持久性是免费的。根据我的经验,这是一种相当迟钝的测试方法,我强烈建议反对它。

其他方法首先要意识到您实际上并没有编写单元测试,而是编写集成测试,因为您正在测试与数据库层集成的应用程序逻辑。

内存数据库方式:

使用内存数据库,让每个测试创建一个在测试结束时丢弃的新数据库。不幸的是,这意味着重新启动整个数据库层,如果你像ORM一样使用重量级的东西,这意味着每次测试都会增加巨大的性能开销。

交易方式:

让每个测试方法启动一个事务,一旦完成,就回滚它。这是做事的首选方式。在某些情况下,您甚至可以使用@Transactional注释您的测试方法,如果所有其他所需的魔法是正确的,那么可能会为您处理事务。再说一遍,注释你永远不会知道某件事是否真的会发生,在这种情况下,如果事务性没有发生那么你就毁了你的数据库,所以我的偏好是从@Transactional保持清醒并编码我的交易开始和我自己的事务回滚。