Bots eenheidstest

VAN TOEPASSING OP: SDK v4

In dit onderwerp laten we u zien hoe u het volgende kunt doen:

  • Eenheidstests voor bots maken.
  • Gebruik assert om te controleren op activiteiten die worden geretourneerd door een dialoogvenster tegen verwachte waarden.
  • Gebruik assert om de resultaten te controleren die door een dialoogvenster worden geretourneerd.
  • Verschillende typen gegevensgestuurde tests maken.
  • Maak mockobjecten voor de verschillende afhankelijkheden van een dialoogvenster, zoals taalherkenning, enzovoort.

Vereisten

Het voorbeeld corebottests dat in dit onderwerp wordt gebruikt, verwijst naar het Microsoft.Bot.Builder.Testing-pakket , XUnit en Moq om eenheidstests te maken.

Het kernbotvoorbeeld maakt gebruik van Language Understanding (LUIS) om gebruikersintenties te identificeren; Het identificeren van gebruikersintentie is echter niet de focus van dit artikel. Zie Voor informatie over het identificeren van gebruikersintenties natuurlijke taal en het toevoegen van natuurlijke taal aan uw bot.

Notitie

Language Understanding (LUIS) wordt op 1 oktober 2025 buiten gebruik gesteld. Vanaf 1 april 2023 kunt u geen nieuwe LUIS-resources maken. Er is nu een nieuwere versie van taalkennis beschikbaar als onderdeel van Azure AI Language.

Conversational Language Understanding (CLU), een functie van Azure AI Language, is de bijgewerkte versie van LUIS. Zie Natuurlijke taalkennis voor meer informatie over ondersteuning voor taalkennis in de Bot Framework SDK.

Dialoogvensters testen

In het CoreBot-voorbeeld worden dialoogvensters getest via de DialogTestClient klasse, die een mechanisme biedt voor het testen ervan in isolatie buiten een bot en zonder dat u uw code hoeft te implementeren in een webservice.

Met deze klasse kunt u eenheidstests schrijven waarmee dialoogvensters worden gevalideerd op basis van een turn-by-turn-basis. Eenheidstests met behulp van DialogTestClient klasse moeten werken met andere dialoogvensters die zijn gebouwd met behulp van de botbuilder-dialoogvensterbibliotheek.

In het volgende voorbeeld ziet u tests die zijn afgeleid van DialogTestClient:

var sut = new BookingDialog();
var testClient = new DialogTestClient(Channels.Msteams, sut);

var reply = await testClient.SendActivityAsync<IMessageActivity>("hi");
Assert.Equal("Where would you like to travel to?", reply.Text);

reply = await testClient.SendActivityAsync<IMessageActivity>("Seattle");
Assert.Equal("Where are you traveling from?", reply.Text);

reply = await testClient.SendActivityAsync<IMessageActivity>("New York");
Assert.Equal("When would you like to travel?", reply.Text);

reply = await testClient.SendActivityAsync<IMessageActivity>("tomorrow");
Assert.Equal("OK, I will book a flight from Seattle to New York for tomorrow, Is this Correct?", reply.Text);

reply = await testClient.SendActivityAsync<IMessageActivity>("yes");
Assert.Equal("Sure thing, wait while I finalize your reservation...", reply.Text);

reply = testClient.GetNextReply<IMessageActivity>();
Assert.Equal("All set, I have booked your flight to Seattle for tomorrow", reply.Text);

De DialogTestClient klasse wordt gedefinieerd in de Microsoft.Bot.Builder.Testing naamruimte en opgenomen in het NuGet-pakket Microsoft.Bot.Builder.Testing .

DialogTestClient

De eerste parameter DialogTestClient is het doelkanaal. Hiermee kunt u verschillende renderinglogica testen op basis van het doelkanaal voor uw bot (Teams, Slack enzovoort). Als u twijfelt over uw doelkanaal, kunt u de Emulator id's of Test kanaal-id's gebruiken, maar houd er rekening mee dat sommige onderdelen zich mogelijk anders gedragen, afhankelijk van het huidige kanaal, ConfirmPrompt bijvoorbeeld de ja/nee-opties voor de Test en Emulator kanalen anders weergeven. U kunt deze parameter ook gebruiken om voorwaardelijke renderinglogica in uw dialoogvenster te testen op basis van de kanaal-id.

De tweede parameter is een exemplaar van het dialoogvenster dat wordt getest. In de voorbeeldcode in dit artikel sut vertegenwoordigt u het systeem dat wordt getest.

De DialogTestClient constructor biedt aanvullende parameters waarmee u het clientgedrag verder kunt aanpassen of parameters kunt doorgeven aan het dialoogvenster dat indien nodig wordt getest. U kunt initialisatiegegevens doorgeven voor het dialoogvenster, aangepaste middleware toevoegen of uw eigen TestAdapter en ConversationState exemplaar gebruiken.

Berichten verzenden en ontvangen

Met de SendActivityAsync<IActivity> methode kunt u een tekstuiting of een IActivity tekstuiting naar het dialoogvenster verzenden en het eerste bericht retourneren dat het ontvangt. De <T> parameter wordt gebruikt om een sterk getypt exemplaar van het antwoord te retourneren, zodat u deze kunt bevestigen zonder dat u deze hoeft te casten.

var reply = await testClient.SendActivityAsync<IMessageActivity>("hi");
Assert.Equal("Where would you like to travel to?", reply.Text);

In sommige scenario's kan uw bot verschillende berichten verzenden als reactie op één activiteit, in deze gevallen DialogTestClient worden de antwoorden in de wachtrij geplaatst en kunt u de GetNextReply<IActivity> methode gebruiken om het volgende bericht uit de antwoordwachtrij te plaatsen.

reply = testClient.GetNextReply<IMessageActivity>();
Assert.Equal("All set, I have booked your flight to Seattle for tomorrow", reply.Text);

GetNextReply<IActivity> retourneert null als er geen verdere berichten in de antwoordwachtrij staan.

Activiteiten bevestigen

De code in het CoreBot-voorbeeld bevestigt alleen de Text eigenschap van de geretourneerde activiteiten. In complexere bots wilt u mogelijk andere eigenschappen, zoals Speak, InputHint, ChannelDataenzovoort, asserteren.

Assert.Equal("Sure thing, wait while I finalize your reservation...", reply.Text);
Assert.Equal("One moment please...", reply.Speak);
Assert.Equal(InputHints.IgnoringInput, reply.InputHint);

U kunt dit doen door elke eigenschap afzonderlijk te controleren zoals hierboven wordt weergegeven, u kunt uw eigen helperhulpprogramma's schrijven voor het bevestigen van activiteiten of u kunt andere frameworks zoals FluentAssertions gebruiken om aangepaste asserties te schrijven en uw testcode te vereenvoudigen.

Parameters doorgeven aan uw dialoogvensters

De DialogTestClient constructor heeft een initialDialogOptions constructor die kan worden gebruikt om parameters door te geven aan het dialoogvenster. In dit voorbeeld wordt bijvoorbeeld MainDialog een BookingDetails object geïnitialiseerd op basis van de resultaten van taalherkenning, met de entiteiten die worden omgezet uit de uiting van de gebruiker en wordt dit object doorgegeven in de aanroep om aan te roepen BookingDialog.

U kunt dit als volgt in een test implementeren:

var inputDialogParams = new BookingDetails()
{
    Destination = "Seattle",
    TravelDate = $"{DateTime.UtcNow.AddDays(1):yyyy-MM-dd}"
};

var sut = new BookingDialog();
var testClient = new DialogTestClient(Channels.Msteams, sut, inputDialogParams);

BookingDialogontvangt deze parameter en opent deze in de test op dezelfde manier als wanneer deze wordt aangeroepen.MainDialog

private async Task<DialogTurnResult> DestinationStepAsync(WaterfallStepContext stepContext, CancellationToken cancellationToken)
{
    var bookingDetails = (BookingDetails)stepContext.Options;
    ...
}

Resultaten van dialoogvenster bevestigen

Sommige dialoogvensters vinden het leuk BookingDialog of DateResolverDialog retourneren een waarde in het dialoogvenster voor aanroepen. Het DialogTestClient object geeft een DialogTurnResult eigenschap weer die kan worden gebruikt om de resultaten te analyseren en te bevestigen die door het dialoogvenster worden geretourneerd.

Bijvoorbeeld:

var sut = new BookingDialog();
var testClient = new DialogTestClient(Channels.Msteams, sut);

var reply = await testClient.SendActivityAsync<IMessageActivity>("hi");
Assert.Equal("Where would you like to travel to?", reply.Text);

...

var bookingResults = (BookingDetails)testClient.DialogTurnResult.Result;
Assert.Equal("New York", bookingResults?.Origin);
Assert.Equal("Seattle", bookingResults?.Destination);
Assert.Equal("2019-06-21", bookingResults?.TravelDate);

De DialogTurnResult eigenschap kan ook worden gebruikt om tussenliggende resultaten te inspecteren en te bevestigen die worden geretourneerd door de stappen in een waterval.

Testuitvoer analyseren

Soms is het nodig om een transcriptie van een eenheidstest te lezen om de testuitvoering te analyseren zonder fouten in de test op te sporen.

Het pakket Microsoft.Bot.Builder.Testing bevat een XUnitDialogTestLogger pakket waarin de berichten die door het dialoogvenster worden verzonden en ontvangen, worden in de console opgeslagen.

Als u deze middleware wilt gebruiken, moet uw test een constructor beschikbaar maken die een ITestOutputHelper object ontvangt dat wordt geleverd door de XUnit-testrunner en een XUnitDialogTestLogger object maakt dat wordt doorgegeven DialogTestClient via de middlewares parameter.

public class BookingDialogTests
{
    private readonly IMiddleware[] _middlewares;

    public BookingDialogTests(ITestOutputHelper output)
        : base(output)
    {
        _middlewares = new[] { new XUnitDialogTestLogger(output) };
    }

    [Fact]
    public async Task SomeBookingDialogTest()
    {
        // Arrange
        var sut = new BookingDialog();
        var testClient = new DialogTestClient(Channels.Msteams, sut, middlewares: _middlewares);

        ...
    }
}

Hier volgt een voorbeeld van wat de XUnitDialogTestLogger logboeken naar het uitvoervenster zijn geconfigureerd:

Example middleware output from XUnit.

Zie Captureing Output in de XUnit-documentatie voor meer informatie over het verzenden van testuitvoer naar de console wanneer u XUnit gebruikt.

Deze uitvoer wordt ook geregistreerd op de buildserver tijdens de builds voor continue integratie en helpt u bij het analyseren van buildfouten.

Gegevensgestuurde tests

In de meeste gevallen verandert de dialoogvensterlogica niet en zijn de verschillende uitvoeringspaden in een gesprek gebaseerd op de uitingen van de gebruiker. In plaats van één eenheidstest te schrijven voor elke variant in het gesprek, is het eenvoudiger om gegevensgestuurde tests (ook wel geparameteriseerde test genoemd) te gebruiken.

De voorbeeldtest in de overzichtssectie van dit document laat bijvoorbeeld zien hoe u één uitvoeringsstroom test, maar niet andere, zoals:

  • Wat gebeurt er als de gebruiker nee op de bevestiging zegt?
  • Wat gebeurt er als ze een andere datum gebruiken?

Met gegevensgestuurde tests kunnen we al deze permutaties testen zonder de tests opnieuw te hoeven schrijven.

In het CoreBot-voorbeeld gebruiken Theory we tests van XUnit om tests te parameteriseren.

Theorietests met behulp van InlineData

Met de volgende test wordt gecontroleerd of een dialoogvenster wordt geannuleerd wanneer de gebruiker 'annuleren' zegt.

[Fact]
public async Task ShouldBeAbleToCancel()
{
    var sut = new TestCancelAndHelpDialog();
    var testClient = new DialogTestClient(Channels.Test, sut);

    var reply = await testClient.SendActivityAsync<IMessageActivity>("Hi");
    Assert.Equal("Hi there", reply.Text);
    Assert.Equal(DialogTurnStatus.Waiting, testClient.DialogTurnResult.Status);

    reply = await testClient.SendActivityAsync<IMessageActivity>("cancel");
    Assert.Equal("Cancelling...", reply.Text);
}

Als u een dialoogvenster wilt annuleren, kunnen gebruikers 'afsluiten', 'nooit erg' en 'stoppen'. In plaats van InlineData een nieuwe testcase te schrijven voor elk mogelijk woord, schrijft u één Theory testmethode die parameters accepteert via een lijst met waarden om de parameters voor elke testcase te definiëren:

[Theory]
[InlineData("cancel")]
[InlineData("quit")]
[InlineData("never mind")]
[InlineData("stop it")]
public async Task ShouldBeAbleToCancel(string cancelUtterance)
{
    var sut = new TestCancelAndHelpDialog();
    var testClient = new DialogTestClient(Channels.Test, sut, middlewares: _middlewares);

    var reply = await testClient.SendActivityAsync<IMessageActivity>("Hi");
    Assert.Equal("Hi there", reply.Text);
    Assert.Equal(DialogTurnStatus.Waiting, testClient.DialogTurnResult.Status);

    reply = await testClient.SendActivityAsync<IMessageActivity>(cancelUtterance);
    Assert.Equal("Cancelling...", reply.Text);
}

De nieuwe test wordt vier keer uitgevoerd met de verschillende parameters en elke case wordt weergegeven als een onderliggend item onder de ShouldBeAbleToCancel test in Visual Studio Test Explorer. Als een van deze mislukt zoals hieronder wordt weergegeven, kunt u met de rechtermuisknop klikken en fouten opsporen in het scenario dat is mislukt in plaats van de volledige set tests opnieuw uit te voeren.

Example test results for in-line data.

Theorietests met behulp van MemberData en complexe typen

InlineData is handig voor kleine gegevensgestuurde tests die eenvoudige waardetypeparameters (tekenreeks, int enzovoort) ontvangen.

Het BookingDialog ontvangt een BookingDetails object en retourneert een nieuw BookingDetails object. Een niet-geparameteriseerde versie van een test voor dit dialoogvenster ziet er als volgt uit:

[Fact]
public async Task DialogFlow()
{
    // Initial parameters
    var initialBookingDetails = new BookingDetails
    {
        Origin = "Seattle",
        Destination = null,
        TravelDate = null,
    };

    // Expected booking details
    var expectedBookingDetails = new BookingDetails
    {
        Origin = "Seattle",
        Destination = "New York",
        TravelDate = "2019-06-25",
    };

    var sut = new BookingDialog();
    var testClient = new DialogTestClient(Channels.Test, sut, initialBookingDetails);

    // Act/Assert
    var reply = await testClient.SendActivityAsync<IMessageActivity>("hi");
    ...

    var bookingResults = (BookingDetails)testClient.DialogTurnResult.Result;
    Assert.Equal(expectedBookingDetails.Origin, bookingResults?.Origin);
    Assert.Equal(expectedBookingDetails.Destination, bookingResults?.Destination);
    Assert.Equal(expectedBookingDetails.TravelDate, bookingResults?.TravelDate);
}

Om deze test te parameteriseren, hebben we een BookingDialogTestCase klasse gemaakt die onze testcasegegevens bevat. Het bevat het oorspronkelijke BookingDetails object, de verwachte BookingDetails en een matrix met tekenreeksen die de uitingen bevatten die van de gebruiker zijn verzonden en de verwachte antwoorden uit het dialoogvenster voor elke beurt.

public class BookingDialogTestCase
{
    public BookingDetails InitialBookingDetails { get; set; }

    public string[,] UtterancesAndReplies { get; set; }

    public BookingDetails ExpectedBookingDetails { get; set; }
}

We hebben ook een helperklasse BookingDialogTestsDataGenerator gemaakt waarmee een IEnumerable<object[]> BookingFlows() methode wordt weergegeven die een verzameling testcases retourneert die door de test moeten worden gebruikt.

Om elke testcase weer te geven als een afzonderlijk item in Visual Studio Test Explorer, vereist de XUnit-testloper dat complexe typen, zoals BookingDialogTestCase implementeren IXunitSerializable, om dit te vereenvoudigen, het Bot.Builder.Testing-framework een TestDataObject klasse biedt die deze interface implementeert en kan worden gebruikt om de testcasegegevens te verpakken zonder te hoeven implementeren IXunitSerializable.

Hier volgt een fragment waarin IEnumerable<object[]> BookingFlows() wordt getoond hoe de twee klassen worden gebruikt:

public static class BookingDialogTestsDataGenerator
{
    public static IEnumerable<object[]> BookingFlows()
    {
        // Create the first test case object
        var testCaseData = new BookingDialogTestCase
        {
            InitialBookingDetails = new BookingDetails(),
            UtterancesAndReplies = new[,]
            {
                { "hi", "Where would you like to travel to?" },
                { "Seattle", "Where are you traveling from?" },
                { "New York", "When would you like to travel?" },
                { "tomorrow", $"Please confirm, I have you traveling to: Seattle from: New York on: {DateTime.Now.AddDays(1):yyyy-MM-dd}. Is this correct? (1) Yes or (2) No" },
                { "yes", null },
            },
            ExpectedBookingDetails = new BookingDetails
            {
                Destination = "Seattle",
                Origin = "New York",
                TravelDate = $"{DateTime.Now.AddDays(1):yyyy-MM-dd}",
            }, 
        };
        // wrap the test case object into TestDataObject and return it.
        yield return new object[] { new TestDataObject(testCaseData) };

        // Create the second test case object
        testCaseData = new BookingDialogTestCase
        {
            InitialBookingDetails = new BookingDetails
            {
                Destination = "Seattle",
                Origin = "New York",
                TravelDate = null,
            },
            UtterancesAndReplies = new[,]
            {
                { "hi", "When would you like to travel?" },
                { "tomorrow", $"Please confirm, I have you traveling to: Seattle from: New York on: {DateTime.Now.AddDays(1):yyyy-MM-dd}. Is this correct? (1) Yes or (2) No" },
                { "yes", null },
            },
            ExpectedBookingDetails = new BookingDetails
            {
                Destination = "Seattle",
                Origin = "New York",
                TravelDate = $"{DateTime.Now.AddDays(1):yyyy-MM-dd}",
            },
        };
        // wrap the test case object into TestDataObject and return it.
        yield return new object[] { new TestDataObject(testCaseData) };
    }
}

Zodra we een object maken voor het opslaan van de testgegevens en een klasse die een verzameling testcases beschikbaar maakt, gebruiken we het kenmerk XUnit MemberData in plaats van InlineData de gegevens in de test in te voeren. De eerste parameter hiervoor MemberData is de naam van de statische functie die de verzameling testcases retourneert en de tweede parameter is het type van de klasse die deze methode beschikbaar maakt.

[Theory]
[MemberData(nameof(BookingDialogTestsDataGenerator.BookingFlows), MemberType = typeof(BookingDialogTestsDataGenerator))]
public async Task DialogFlowUseCases(TestDataObject testData)
{
    // Get the test data instance from TestDataObject
    var bookingTestData = testData.GetObject<BookingDialogTestCase>();
    var sut = new BookingDialog();
    var testClient = new DialogTestClient(Channels.Test, sut, bookingTestData.InitialBookingDetails);

    // Iterate over the utterances and replies array.
    for (var i = 0; i < bookingTestData.UtterancesAndReplies.GetLength(0); i++)
    {
        var reply = await testClient.SendActivityAsync<IMessageActivity>(bookingTestData.UtterancesAndReplies[i, 0]);
        Assert.Equal(bookingTestData.UtterancesAndReplies[i, 1], reply?.Text);
    }

    // Assert the resulting BookingDetails object
    var bookingResults = (BookingDetails)testClient.DialogTurnResult.Result;
    Assert.Equal(bookingTestData.ExpectedBookingDetails?.Origin, bookingResults?.Origin);
    Assert.Equal(bookingTestData.ExpectedBookingDetails?.Destination, bookingResults?.Destination);
    Assert.Equal(bookingTestData.ExpectedBookingDetails?.TravelDate, bookingResults?.TravelDate);
}

Hier volgt een voorbeeld van de resultaten voor de DialogFlowUseCases tests in Visual Studio Test Explorer wanneer de test wordt uitgevoerd:

Example results for the booking dialog.

Mocks gebruiken

U kunt mock-elementen gebruiken voor de dingen die momenteel niet zijn getest. Ter referentie kan dit niveau over het algemeen worden beschouwd als eenheids- en integratietests.

Door zoveel elementen te bespotten als u kunt, kunt u het stuk dat u test beter isoleren. Kandidaten voor mock-elementen zijn opslag, de adapter, middleware, activiteitspijplijn, kanalen en alles wat niet rechtstreeks deel uitmaakt van uw bot. Dit kan ook betekenen dat bepaalde aspecten tijdelijk worden verwijderd, zoals middleware die niet betrokken is bij het deel van uw bot dat u test, om elk stuk te isoleren. Als u echter uw middleware test, kunt u in plaats daarvan uw bot mocken.

Mocking-elementen kunnen enkele vormen aannemen, van het vervangen van een element door een ander bekend object om minimale hallo wereldfunctionaliteit te implementeren. Dit kan ook de vorm aannemen van het verwijderen van het element, als het niet nodig is of het afdwingen om niets te doen.

Met mocks kunnen we de afhankelijkheden van een dialoogvenster configureren en ervoor zorgen dat ze zich tijdens de uitvoering van de test in een bekende status bevinden zonder dat we hoeven te vertrouwen op externe resources, zoals databases, taalmodellen of andere objecten.

Als u het dialoogvenster gemakkelijker wilt testen en de afhankelijkheden van externe objecten wilt verminderen, moet u mogelijk de externe afhankelijkheden in de dialoogvensterconstructor injecteren.

Bijvoorbeeld, in plaats van instantiëren BookingDialog in MainDialog:

public MainDialog()
    : base(nameof(MainDialog))
{
    ...
    AddDialog(new BookingDialog());
    ...
}

We geven een exemplaar van BookingDialog als constructorparameter door:

public MainDialog(BookingDialog bookingDialog)
    : base(nameof(MainDialog))
{
    ...
    AddDialog(bookingDialog);
    ...
}

Hierdoor kunnen we het BookingDialog exemplaar vervangen door een mock-object en eenheidstests schrijven voor MainDialog zonder de werkelijke BookingDialog klasse aan te roepen.

// Create the mock object
var mockDialog = new Mock<BookingDialog>();

// Use the mock object to instantiate MainDialog
var sut = new MainDialog(mockDialog.Object);

var testClient = new DialogTestClient(Channels.Test, sut);

Dialoogvensters met mocking

Zoals hierboven beschreven, MainDialog wordt aangeroepen BookingDialog om het BookingDetails object te verkrijgen. We implementeren en configureren als volgt een mock-exemplaar BookingDialog :

// Create the mock object for BookingDialog.
var mockDialog = new Mock<BookingDialog>();
mockDialog
    .Setup(x => x.BeginDialogAsync(It.IsAny<DialogContext>(), It.IsAny<object>(), It.IsAny<CancellationToken>()))
    .Returns(async (DialogContext dialogContext, object options, CancellationToken cancellationToken) =>
    {
        // Send a generic activity so we can assert that the dialog was invoked.
        await dialogContext.Context.SendActivityAsync($"{mockDialogNameTypeName} mock invoked", cancellationToken: cancellationToken);

        // Create the BookingDetails instance we want the mock object to return.
        var expectedBookingDialogResult = new BookingDetails()
        {
            Destination = "Seattle",
            Origin = "New York",
            TravelDate = $"{DateTime.UtcNow.AddDays(1):yyyy-MM-dd}"
        };

        // Return the BookingDetails we need without executing the dialog logic.
        return await dialogContext.EndDialogAsync(expectedBookingDialogResult, cancellationToken);
    });

// Create the sut (System Under Test) using the mock booking dialog.
var sut = new MainDialog(mockDialog.Object);

In dit voorbeeld hebben we Moq gebruikt om het mockdialoogvenster en de Setup methoden Returns te maken om het gedrag ervan te configureren.

Luis-resultaten nasimuleerden

Notitie

Language Understanding (LUIS) wordt op 1 oktober 2025 buiten gebruik gesteld. Vanaf 1 april 2023 kunt u geen nieuwe LUIS-resources maken. Er is nu een nieuwere versie van taalkennis beschikbaar als onderdeel van Azure AI Language.

Conversational Language Understanding (CLU), een functie van Azure AI Language, is de bijgewerkte versie van LUIS. Zie Natuurlijke taalkennis voor meer informatie over ondersteuning voor taalkennis in de Bot Framework SDK.

In eenvoudige scenario's kunt u mock LUIS-resultaten als volgt implementeren via code:

var mockRecognizer = new Mock<IRecognizer>();
mockRecognizer
    .Setup(x => x.RecognizeAsync<FlightBooking>(It.IsAny<ITurnContext>(), It.IsAny<CancellationToken>()))
    .Returns(() =>
    {
        var luisResult = new FlightBooking
        {
            Intents = new Dictionary<FlightBooking.Intent, IntentScore>
            {
                { FlightBooking.Intent.BookFlight, new IntentScore() { Score = 1 } },
            },
            Entities = new FlightBooking._Entities(),
        };
        return Task.FromResult(luisResult);
    });

LUIS-resultaten kunnen complex zijn. Wanneer dat het is, is het eenvoudiger om het gewenste resultaat vast te leggen in een JSON-bestand, het toe te voegen als een resource aan uw project en het te deserialiseren in een LUIS-resultaat. Hier volgt een voorbeeld:

var mockRecognizer = new Mock<IRecognizer>();
mockRecognizer
    .Setup(x => x.RecognizeAsync<FlightBooking>(It.IsAny<ITurnContext>(), It.IsAny<CancellationToken>()))
    .Returns(() =>
    {
        // Deserialize the LUIS result from embedded json file in the TestData folder.
        var bookingResult = GetEmbeddedTestData($"{GetType().Namespace}.TestData.FlightToMadrid.json");

        // Return the deserialized LUIS result.
        return Task.FromResult(bookingResult);
    });

Aanvullende informatie