如何使用异步函数测试API控制器?

问题描述:

我想单元测试我的API控制器使用MSTest。我正在关注这里提到的教程:https://www.asp.net/web-api/overview/testing-and-debugging/mocking-entity-framework-when-unit-testing-aspnet-web-api-2如何使用异步函数测试API控制器?

上面的教程很遗憾没有涵盖使控制器中的异步函数工作的调整。

在下面的代码中,如果我在非异步控制器操作上运行它,测试会成功运行。但是当我在异步函数上测试它时,它给了我一个错误。

public async Task GetService_ShouldReturnCorrectServiceId() 
{ 
    //Arrange 
    var context = new TestContext(); 
    context.Services.Add(new Service { Service_ID = 1, Service_Name = "WEBAPPS"}); 

    //Act 
    var controller = new ServicesController(context); 
    var result = await controller.GetServiceId("WEBAPPS") as OkNegotiatedContentResult<Service>; 

    //Assert 
    Assert.IsNotNull(result); 
    Assert.AreEqual(1, result.Content.Service_ID); 
    } 

测试失败给这个错误:

the provider for the source iqueryable doesn't implement idbasyncqueryprovider

我控制器的方法是:

public async Task<IHttpActionResult> GetServiceId(string name) 
{ 

    var service_id = await db.Services 
        .Where(s => (s.Service_Name == name)) 
        .FirstOrDefaultAsync(); 
    if (service_id == null) 
    { 
     return NotFound(); 
    } 

    return Ok(service_id); 
} 

而且TestContext都会文件是:

class TestContext : IContext 
{ 
    public TestContext() 
    { 
     this.Services = new TestServiceDbSet(); 
    } 

    public DbSet<Service> Services { get; set; } 

    public void Dispose() { } 
} 

而且我是按照所有关于该链接信件的步骤都包括在内即我认为TestDbSet代码(请参阅该链接)必须更新以解释异步方法,但我不知道如何。

感谢任何帮助!谢谢。

+0

它是您的“TestServiceDbSet”类型的实现。有两种可能的方式来实现它,第一种方式不适用于'async'代码,只有第二种方法可以。不幸的是,你链接到的例子没有提到这一点。请参阅[使用您自己的测试双打进行测试](https://msdn.microsoft.com/zh-cn/data/dn314431.aspx)。我为此写了一些扩展,以便在整个测试项目中重用,请参阅[DbContext Data Mocking for Unit Testing](https://github.com/IgorWolbers/DbContextMockForUnitTests) – Igor

+0

@Igor谢谢!会看看。有没有更简单的方法来测试这个使用moq/nunit? – 90abyss

+0

测试装具并不重要。就创造假货而言,我更喜欢NSubstitute(可通过NuGet获得),但我认为这也不重要,它更偏向个人。尽管您的设计对测试能力影响最大。尽可能保持抽象/一般的控制器内的类型引用是确保测试非常简单的最佳方法。当使用EF我使用引用类型的DbContext永不派生类型和使用Set ()来获取DbSets ,那么它很容易在控制器或服务注入假的DbContext与嘲笑集。 – Igor

您将需要实现一个异步QueryProvider。请参阅this文章中的使用异步查询进行测试。