使用实体框架和异步方法进行 C# 集成测试

本文关键字:集成测试 异步方法 实体 框架 | 更新日期: 2023-09-27 18:30:27

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

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

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 中失败并出现异常,并显示消息:等待操作时间限制超出或像这样,因为它被翻译成我的母语......

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

如果有人能对这个问题有所了解,我将不胜感激。

使用实体框架和异步方法进行 C# 集成测试

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();
}