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
, ChannelData
enzovoort, 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);
BookingDialog
ontvangt 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:
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.
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:
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);
});