2016-08-12 4 views
1

Ich versuche Unit-Test meine API-Controller mit MSTest. Ich folge dem Tutorial hier erwähnt: https://www.asp.net/web-api/overview/testing-and-debugging/mocking-entity-framework-when-unit-testing-aspnet-web-api-2Wie API Controller mit asynchronen Funktionen testen?

Das Tutorial oben behandelt leider nicht, welche Optimierungen vorzunehmen, damit es für asynchrone Funktionen in der Steuerung funktioniert.

Im folgenden Code wird der Test erfolgreich ausgeführt, wenn ich ihn bei einer nicht asynchronen Controlleraktion ausführe. Aber wenn ich es auf async Funktion teste, gibt es mir einen Fehler.

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

-Test diesen Fehler fehl geben:

the provider for the source iqueryable doesn't implement idbasyncqueryprovider

Mein Controller-Methode ist:

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

Und die Testcontext-Datei ist:

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

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

    public void Dispose() { } 
} 

Und ich habe gefolgt alle Schritte zum Buchstaben in diesem Link abov e. Ich denke, TestDbSet-Code (siehe diesen Link) muss aktualisiert werden, um Async-Methoden zu berücksichtigen, aber ich bin mir nicht sicher, wie.

Schätzen Sie jede Hilfe! Vielen Dank.

+0

Es ist Ihre Implementierung vom Typ 'TestServiceDbSet'. Es gibt 2 Möglichkeiten, dies zu tun und der erste Weg funktioniert nicht mit 'async' Code, nur der zweite wird es tun. Leider erwähnt das Beispiel, das Sie verknüpften, das nicht. Siehe [Test mit eigenen Testdoppelwerten] (https://msdn.microsoft.com/en-us/data/dn314431.aspx). Ich habe ein paar Erweiterungen geschrieben, um die Wiederverwendung während eines Testprojekts zu erleichtern, siehe [DbContext Data Mocking for Unit Testing] (https://github.com/IgorWolbers/DbContextMockForUnitTests) – Igor

+0

@Igor Danke! Werde einen Blick darauf werfen. Gibt es eine einfachere Möglichkeit, dies mit moq/nunit zu testen? – 90abyss

+0

Das Prüfkabel spielt keine Rolle. Was das Erstellen von Fälschungen betrifft, bevorzuge ich NSubstitute (verfügbar über NuGet), aber ich denke nicht, dass das auch eine Rolle spielt, sondern eher persönliche Vorlieben. Ihr Design hat jedoch den größten Einfluss auf die Testfähigkeit. Wenn Sie Ihre Typreferenzen in Ihrem Controller so abstrakt/allgemein wie möglich halten, ist dies der beste Weg, um sicherzustellen, dass das Testen einfach ist. Bei der Verwendung von EF verwende ich Referenztyp DbContext und nie die abgeleiteten Typen und verwenden Sie das Set (), um die DbSets zu bekommen, dann ist es einfach, einen gefälschten DbContext mit verspottet Set in den Controller oder Service. – Igor

Antwort

1

Sie müssen einen aynchronen QueryProvider implementieren. Werfen Sie einen Blick auf Test mit asynchronen Abfragen in this Artikel.

Verwandte Themen