使用 Entity Framework 和异步方法的 C# 集成测试

标签 c# entity-framework testing

我正在使用单独的测试数据库来测试业务逻辑。然而,我的业务逻辑主要由异步方法组成,这些方法多次等待其他方法。我在测试这些方法时遇到了问题,我已经想不出是什么原因以及如何解决它......

这是我要测试的业务逻辑方法的示例:

public async Task<string> RegisterNewUser(string name, string surname, string address, string city, string phone, string email, string password, string repeatedPassword)
{
    string errorMessage = null;

    Person newUser = new Person();

    // _context is my instance of my class inherited from DBContext
    //Getting the next ID for new user
    if (_context.People.Any())
        newUser.Id = await _context.People.MaxAsync(record => record.Id) + 1;
    else
        newUser.Id = 0;

    newUser.Name = name;
    newUser.Surname = surname;
    newUser.Address = address;
    newUser.City = city;
    newUser.Phone = phone;
    newUser.Email = email;
    newUser.Password = password;

    bool validationSuccessful = true;

    if (await _context.People.CountAsync(p => p.Email == newUser.Email) > 0)
    {
        errorMessage = "Given email address is already taken";
        validationSuccessful = false;
    }

    if (validationSuccessful)
    {
        try
        {
            // Adding user to database
            newUser.Password = GetHashedPassword(newUser.Password);
            _context.People.Add(newUser);

            // Adding activation info to database
            RegistrationActivation act = new RegistrationActivation() { PersonId = newUser.Id, ActivationKey = "blabla"};
            _context.RegistrationActivations.Add(act);

            await _context.SaveChangesAsync();
        }
        catch (Exception e)
        {
             Exception exc = e;

             while (exc.InnerException != null)
             {
                 exc = exc.InnerException;
                 errorMessage = "Exception - " + exc.Message;
             }
        }

        return errorMessage;
    }
}

这是我的实际测试方法:

[TestMethod]
public void Login()
{
    Person registered = PersonTestData.CreateGoodTestUser();

    string error = UnitOfWork.CrudServices.MyPersonRepository.RegisterNewUser
                (registered.Name, registered.Surname, registered.Address, registered.City, registered.Phone, registered.Email, registered.Password, registered.Password).Result;

    Assert.IsTrue(error == null, error);
}

上面代码中的 UnitOfWork 只是一个对象,在开始时为每个测试方法实例化,并在它完成后进行处理。它连接测试数据库并提供对存储库中业务逻辑方法的访问。

在当前的形式中,测试将失败,并在 RegisterNewUser 中出现异常,并显示消息:WAITING操作时间限制超出或类似这样,因为它已翻译成我的母语...

现在,如果我注释掉添加用户和添加激活信息的代码(_context.SaveChangesAsync() 之前的 4 行),测试将通过。 此外,如果我从 RegisterNewUser 方法中删除所有异步/等待功能 - 即不使用等待和使用不带异步后缀的方法而不删除上述行 - 测试也将通过......

如果有人能阐明这个问题,我将不胜感激。

最佳答案

Stephen Cleary 为您提供异步任何方面所需的所有答案 - http://blog.stephencleary.com/2012/02/async-unit-tests-part-2-right-way.html .

除了 Stephen 关于异步单元测试的出色建议,您还可以尝试使用 XUnit,它支持开箱即用的异步单元测试方法,例如

[Fact]
public async void MyTest() 
{
    var temp = await SomeAsyncMethod();
}

关于使用 Entity Framework 和异步方法的 C# 集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34807339/

相关文章:

java - 在java测试中没有收到错误

c# - 在集合中查找非重复数字的列表。这可以做得更有效/更短的代码吗?

c# - First <>扩展方法是否有安全版本?

c# - c#中的数据表到XML,其中一些项目是列表<object>

c# - Enum.TryParse 对任何数值返回 true

.net - EF 查询包含 "Distinct()"第一次慢

entity-framework - SQL Server 2005 的代码优先?

c++ - basic_string 等价物的单元测试

c# - 使用 DbContext 和 TenantId 的 Multi-Tenancy - 拦截器、过滤器、EF 代码优先

unit-testing - Joomla 3.0——用于测试目的的独立应用程序