I would like to instantiate a turnContext to be used in integration testing. How would I be able to instantiate one without calling on the processActivity() method of the adapter?
I am looking at the documentation but it shows that I would need the request of the post call as the parameter. I would like my testing to be independant of the post call. I would then assume that I would need to instantiate the request? How would I go about doing so?
This is a bit hard to answer without knowing how you are planning to use the code. That being said, it's not that hard to create a new turnContext and also bypass the processActivity(). Given how you are referencing turnContext and processActivity(), I'm assuming you are using the Node SDK. Implementing in C# wouldn't be too different.
Here are two options, both utilizing the creation of a new adapter, however you can also pass in an already established turnContext, if desired:
Option 1: In the index.js file, you will want to create a new adapter or make a copy of the first depending on your needs:
const adapter = new BotFrameworkAdapter({
appId: endpointConfig.appId || process.env.MicrosoftAppId,
appPassword: endpointConfig.appPassword || process.env.MicrosoftAppPassword
});
const newAdapter = adapter;
or
const adapter = new BotFrameworkAdapter({
appId: endpointConfig.appId || process.env.MicrosoftAppId,
appPassword: endpointConfig.appPassword || process.env.MicrosoftAppPassword
});
const newAdapter = new BotFrameworkAdapter({
appId: endpointConfig.appId || process.env.MicrosoftAppId,
appPassword: endpointConfig.appPassword || process.env.MicrosoftAppPassword
});
Include the onTurnError code to catch errors:
// Catch-all for errors.
adapter.onTurnError = async (context, error) => {
console.error(`\n [onTurnError]: ${ error }`);
await context.sendActivity(`Oops. Something went wrong!`);
};
// Catch-all for errors.
newAdapter.onTurnError = async (context, error) => {
console.error(`\n [onTurnError]: ${ error }`);
await context.sendActivity(`Oops. Something went wrong!`);
};
Then, set the new adapters and create the new turnContext:
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (turnContext) => {
await bot.onTurn(turnContext);
});
newAdapter.createContext(req, res);
});
Options 2: In the index.js file, building off of the above code, set the adapters to await the individual "onTurn" methods:
// Listen for incoming requests.
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (turnContext) => {
await bot.onTurn(turnContext);
});
newAdapter.processActivity(req, res, async (turnContext) => {
await bot.newOnTurn(turnContext);
});
});
In the bot.js file, you will have your two "onTurn" methods. In this example, the different "onTurn" methods are called based on whether a message is sent or I am deleting user data (I am sending this event via the Emulator => Conversation menu item). What you decide to match on is up to you.
async newOnTurn(turnContext) {
if (turnContext.activity.type === ActivityTypes.DeleteUserData) {
const dc = await this.dialogs.createContext(turnContext);
await dc.context.sendActivity(`Looks like you deleted some user data.`);
}
}
async onTurn(turnContext) {
if (turnContext.activity.type === ActivityTypes.Message) {
const dc = await this.dialogs.createContext(turnContext);
await dc.context.sendActivity(`Looks like you sent a message.`);
}
}
Hope of help!