Skip to content

Commit 20912d5

Browse files
authored
Merge pull request #298185 from wsilveiranz/wsilveiranz-unittest-createfromscratch
Create Logic Apps Standard Unit Tests from an existing Workflow Definition (Preview)
2 parents 21af099 + c4c7d43 commit 20912d5

File tree

4 files changed

+263
-0
lines changed

4 files changed

+263
-0
lines changed
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
---
2+
title: Create Unit Tests from Standard Workflows with Visual Studio Code
3+
description: Create unit tests from Standard workflow definitions in Azure Logic Apps by using Visual Studio Code.
4+
services: logic-apps
5+
ms.suite: integration
6+
author: wsilveiranz
7+
ms.author: wsilveira
8+
ms.reviewer: estfan, azla
9+
ms.topic: how-to
10+
ms.date: 04/14/2025
11+
# Customer intent: As logic app developer, I want to learn how to create a unit test that mocks the operations and outputs from a Standard workflow definition in Azure Logic Apps with Visual Studio Code.
12+
---
13+
14+
# Create unit tests from Standard workflow definitions in Azure Logic Apps with Visual Studio Code (Preview)
15+
16+
> [!NOTE]
17+
>
18+
> This capability is in preview and is subject to the [**Supplemental Terms of Use for Microsoft Azure Previews**](https://azure.microsoft.com/support/legal/preview-supplemental-terms/).
19+
20+
Unit testing is an essential practice that keeps your app or solution reliable and accurate throughout the software development lifecycle. Unit tests help you efficiently and systematically validate the key components in your solution.
21+
22+
For Standard logic app workflows, you can create unit tests by using Visual Studio Code and the Azure Logic Apps (Standard) extension. This capability lets you use workflow definitions to create unit tests and tailor them to scenarios supported by your logic app solution - all without needing connections to any external services, systems, or APIs. This approach lets you test your workflows without having to interact with external services, systems, or APIs and provides the following benefits:
23+
24+
- Improve workflow quality by identifying and addressing potential issues before you deploy to other environments.
25+
26+
- Streamline unit test integration with your development process, while ensuring consistent and accurate workflow behavior.
27+
28+
This guide shows how to create a unit test definition from a workflow. This definition mocks the external calls from each workflow operation without changing the workflow logic. When you create a unit test for a workflow, you get a unit test project that includes the following folders:
29+
30+
- A folder that contains strongly typed classes for each mockable operation in your workflow.
31+
32+
- A folder for each unit test definition. This folder includes a C# file that contains a sample class and methods. You use this class and methods to set up your own assertions, confirm that the workflow behaves as expected, and make sure that the workflow behaves reliably and predictably in your larger Azure ecosystem.
33+
34+
## Prerequisites
35+
36+
- An Azure account and subscription. If you don't have a subscription, [sign up for a free Azure account](https://azure.microsoft.com/free/?WT.mc_id=A261C142F).
37+
38+
- A Standard logic app project in Visual Studio Code that contains at least one workflow definition to use for creating a unit test.
39+
40+
For more information about Visual Studio Code setup and project creation, see [Create Standard logic app workflows with Visual Studio Code](/azure/logic-apps/create-standard-workflows-visual-studio-code).
41+
42+
## Limitations and known issues
43+
44+
- This release currently supports only C# for creating unit tests.
45+
46+
- This release doesn't support non-mocked actions. Make sure that all actions in the workflow execution path are mocked.
47+
48+
- This release doesn't support the following action types:
49+
50+
- Integration account actions
51+
- Data Mapper actions
52+
- Custom code actions
53+
- XML actions
54+
- Liquid actions
55+
- EDI encode and decode actions
56+
57+
## Review the basic concepts
58+
59+
The following list includes basic but important concepts about unit tests for Standard workflows:
60+
61+
- **Logic app unit test**
62+
63+
A controlled workflow execution that injects mock objects. These objects represent either the workflow trigger or actions that depend on external services or systems.
64+
65+
- **Mockable action**
66+
67+
A workflow action that depends on an external service or system. You can convert these actions to mocked actions for unit test creation and execution.
68+
69+
## Create a unit test from a workflow definition
70+
71+
1. In Visual Studio Code, open your Standard logic app project.
72+
73+
1. In your project, expand the workflow definition folder.
74+
75+
1. From the shortcut menu for the **workflow.json** file, select **Open Designer**.
76+
77+
1. On the designer toolbar, select **Create unit test**.
78+
79+
:::image type="content" source="media/create-unit-tests-standard-workflow-definitions-visual-studio-code/designer.png" alt-text="Screenshot shows Visual Studio Code, Standard logic app project, workflow designer, and selected command to create unit test." lightbox="media/create-unit-tests-standard-workflow-definitions-visual-studio-code/designer.png":::
80+
81+
1. Provide a name to use for the unit test, unit test class, and C# file.
82+
83+
A new folder named **Tests** now appears in your project workspace. This folder has the following structure:
84+
85+
:::image type="content" source="media/create-unit-tests-standard-workflow-definitions-visual-studio-code/unit-test-project-structure.png" alt-text="Screenshot shows Visual Studio Code, Standard logic app project, and Tests folder with unit test folders and files." lightbox="media/create-unit-tests-standard-workflow-definitions-visual-studio-code/unit-test-project-structure.png":::
86+
87+
| Folder or file | Description |
88+
|----------------|-------------|
89+
| **`Tests`** <br>**\|\| <`logic-app-name`>** | In the **`Tests`** folder, a **<`logic-app-name`>** folder appears when you add unit tests to a logic app project. |
90+
| **`Tests`** <br>**\|\| <`logic-app-name`>** <br>**\|\|\| <`workflow-name`>** | In the **<`logic-app-name`>** folder, a **<`workflow-name`>** folder appears when you add unit tests for a workflow. |
91+
| **`Tests`** <br>**\|\| <`logic-app-name`>** <br>**\|\|\| <`workflow-name`>** <br>**\|\|\|\| `MockOutputs`** <br>**\|\|\|\|\| <`operation-name-outputs`>**.**`cs`** | In the **<`workflow-name`>** folder, the **`MockOutputs`** folder contains a C# (**.cs**) file with strongly-typed classes for each connector operation in the workflow. Each **.cs** file name uses the following format: <br><br>**<`operation-name`>[`Trigger\|Action`]`Output.cs`** <br><br>If a connector operation has *dynamic contracts*, a class appears for each *dynamic type*. A dynamic type refers to an operation parameter that has different inputs and outputs based on the value provided for that parameter. You can use these classes to extend your unit tests and create new mocks from scratch. |
92+
| **`Tests`** <br>**\|\| <`logic-app-name`>** <br>**\|\|\| <`workflow-name`>** <br>**\|\|\|\| <`unit-test-name`>** <br>**\|\|\|\|\| <`unit-test-name`>`.cs`** | In the **<`workflow-name`>** folder, the **<`unit-test-name`>** folder contains a **<`unit-test-name`>`.cs`** file. You use this file, which contains a sample C# class and methods, to run and assert results. You can edit this file to match your specific test scenarios. |
93+
94+
## Review the unit test *.cs file
95+
96+
This unit test class provides a framework for testing Standard logic app workflows by mocking triggers and actions. This class lets you test workflows without actually calling external services or APIs.
97+
98+
### Test class structure
99+
100+
A typical unit test class uses the following structure:
101+
102+
```csharp
103+
[TestClass]
104+
public class <unit-test-name>
105+
{
106+
public TestExecutor TestExecutor;
107+
108+
[TestInitialize]
109+
public void Setup()
110+
{
111+
this.TestExecutor = new TestExecutor("<workflow-name>/testSettings.config");
112+
}
113+
114+
// Add test methods here.
115+
116+
// Add helper methods here.
117+
}
118+
```
119+
120+
#### Setup() method
121+
122+
This method instantiates the **`TestExecutor`** class by using the path to your test settings configuration file. The method runs before each test execution and creates a new instance of **`TestExecutor`**.
123+
124+
```csharp
125+
[TestInitialize]
126+
public void Setup()
127+
{
128+
this.TestExecutor = new TestExecutor("<workflow-name>/testSettings.config");
129+
}
130+
```
131+
132+
### Sample test methods
133+
134+
The following section describes sample test methods that you can use in your unit test class.
135+
136+
#### Static mock data test
137+
138+
The following method shows how to use static mock data to test your workflow. In this method, you can complete the following tasks:
139+
140+
- Set property values on your mocked actions.
141+
- Execute the workflow with the configured mock data.
142+
- Confirm that the execution succeeded.
143+
144+
```csharp
145+
[TestMethod]
146+
public async Task <workflow-name>_<unit-test-name>_ExecuteWorkflow_SUCCESS_Sample1()
147+
{
148+
// PREPARE mock: Generate mock trigger data.
149+
var triggerMockOutput = new WhenMessagesAreAvailableInAQueuePeeklockTriggerOutput();
150+
// Sample that shows how to set the properties for triggerMockOutput
151+
// triggerMockOutput.Body.Id = "SampleId";
152+
var triggerMock = new WhenMessagesAreAvailableInAQueuePeeklockTriggerMock(outputs: triggerMockOutput);
153+
154+
// Generate mock action data.
155+
var actionMockOutput = new CallExternalAPIActionOutput();
156+
// Sample that shows how to set the properties for actionMockOutput
157+
// actionMockOutput.Body.Name = "SampleResource";
158+
// actionMockOutput.Body.Id = "SampleId";
159+
var actionMock = new CallExternalAPIActionMock(name: "Call_External_API", outputs: actionMockOutput);
160+
161+
// ACT: Create the UnitTestExecutor instance. Run the workflow with mock data.
162+
var testMock = new TestMockDefinition(
163+
triggerMock: triggerMock,
164+
actionMocks: new Dictionary<string, ActionMock>()
165+
{
166+
{actionMock.Name, actionMock}
167+
});
168+
var testRun = await this.TestExecutor
169+
.Create()
170+
.RunWorkflowAsync(testMock: testMock).ConfigureAwait(continueOnCapturedContext: false);
171+
172+
// ASSERT: Confirm successful workflow execution and that the status is 'Succeeded'.
173+
Assert.IsNotNull(value: testRun);
174+
Assert.AreEqual(expected: TestWorkflowStatus.Succeeded, actual: te
175+
stRun.Status);
176+
}
177+
```
178+
179+
#### Dynamic mock data test
180+
181+
The following method shows how to use dynamic mock data with callback methods. This approach gives you two options that dynamically generate mock data:
182+
183+
- Define a separate callback method.
184+
- Use an [inline lambda function](/dotnet/csharp/language-reference/operators/lambda-expressions).
185+
186+
Both approaches let you create dynamic responses based on unit test execution context.
187+
188+
```csharp
189+
[TestMethod]
190+
public async Task <workflow-name>_<unit-test-name>_ExecuteWorkflow_SUCCESS_Sample2()
191+
{
192+
// PREPARE: Generate mock trigger data.
193+
var triggerMockOutput = new WhenMessagesAreAvailableInAQueuePeeklockTriggerOutput();
194+
// Sample that shows how to set triggerMockOutput properties.
195+
// triggerMockOutput.Body.Flag = true;
196+
var triggerMock = new WhenMessagesAreAvailableInAQueuePeeklockTriggerMock(outputs: triggerMockOutput);
197+
198+
// PREPARE: Generate mock action data.
199+
// OPTION 1: Define a callback class.
200+
var actionMock = new CallExternalAPIActionMock(name: "Call_External_API", onGetActionMock: CallExternalAPIActionMockOutputCallback);
201+
202+
// OPTION 2: Define inline with a lambda function.
203+
/*var actionMock = new CallExternalAPIActionMock(name: "Call_External_API", onGetActionMock: (testExecutionContext) =>
204+
{
205+
return new CallExternalAPIActionMock(
206+
status: TestWorkflowStatus.Succeeded,
207+
outputs: new CallExternalAPIActionOutput {
208+
209+
// If this account contains a JObject Body,
210+
// set the properties you want here:
211+
// Body = "something".ToJObject()
212+
213+
}
214+
);
215+
});*/
216+
217+
// ACT: Create the UnitTestExecutor instance. Run the workflow with mock data.
218+
var testMock = new TestMockDefinition(
219+
triggerMock: triggerMock,
220+
actionMocks: new Dictionary<string, ActionMock>()
221+
{
222+
{actionMock.Name, actionMock}
223+
});
224+
var testRun = await this.TestExecutor
225+
.Create()
226+
.RunWorkflowAsync(testMock: testMock).ConfigureAwait(continueOnCapturedContext: false);
227+
228+
// ASSERT: Confirm successful workflow execution and that the status is 'Succeeded'.
229+
Assert.IsNotNull(value: testRun);
230+
Assert.AreEqual(expected: TestWorkflowStatus.Succeeded, actual: testRun.Status);
231+
}
232+
```
233+
234+
### Helper methods
235+
236+
The following section describes methods used by the sample test methods. Helper methods appear under the test methods in the class definition.
237+
238+
#### Callback method
239+
240+
The following method dynamically generates mock data. The method name varies based on the mocked action name in the test methods for static or dynamic mock data. You can edit this method to return different mock responses based on your test scenario requirements or use it as a template to create your own dynamic callback methods.
241+
242+
```csharp
243+
public CallExternalAPIActionMock CallExternalAPIActionMockOutputCallback(TestExecutionContext context)
244+
{
245+
// Sample mock data: Dynamically change the mocked data for 'actionName'.
246+
return new CallExternalAPIActionMock(
247+
status: TestWorkflowStatus.Succeeded,
248+
outputs: new CallExternalAPIActionOutput {
249+
250+
// If this account contains a JObject Body,
251+
// set the properties you want here:
252+
// Body = "something".ToJObject()
253+
254+
}
255+
);
256+
}
257+
```
258+
259+
## Related content
260+
261+
[Create unit tests from Standard workflow runs in Azure Logic Apps with Visual Studio Code](/azure/logic-apps/create-unit-tests-standard-workflow-runs-visual-studio-codes)
46 KB
Loading
Loading

articles/logic-apps/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,8 @@ items:
463463
href: update-workflow-definition-language-schema.md
464464
- name: Test
465465
items:
466+
- name: Create unit tests from Standard workflow definitions
467+
href: create-unit-tests-standard-workflow-definitions-visual-studio-code.md
466468
- name: Test workflows with mock outputs
467469
href: test-logic-apps-mock-data-static-results.md
468470
- name: Deploy

0 commit comments

Comments
 (0)