Hi @Richard Coleman ,
Welcome to Microsoft Q&A Portal. Thank you for reaching out and sharing your C# unit test code.
I understand you are experiencing an issue where a conditional check for null equality works as expected during normal runtime execution but fails with an internal server error during local C# unit testing. Based on the test script you provided, the root cause involves a combination of how the C# mock payload is constructed and how the Logic Apps engine evaluates WDL expressions against null literals during unit tests.
1. Why the C# Test Script Fails
In your test script, the trigger output is defined as:
var triggerMock = new TriggerMock(status: TestWorkflowStatus.Succeeded, name: "test_req", outputs: (MockOutput)null);
Passing (MockOutput)null sets the entire trigger output envelope to a C# null reference. When the local test engine runs, any workflow expression attempting to call triggerBody() or access properties via triggerOutputs() will throw an evaluation error (often manifesting as an Internal Server Error or InvalidTemplate) because the root output structure itself is missing from the mock engine's context.
The Fix for C#: Instead of casting C# null as the entire MockOutput, instantiate a new MockOutput object and pass null or an anonymous object with null properties as the content/body of the mock:
// Option A: Mocking an explicitly null body payload
var triggerMock = new TriggerMock(
status: TestWorkflowStatus.Succeeded,
name: "test_req",
outputs: new MockOutput(content: null)
);
// Option B: Mocking an object with a null property
var triggerMock = new TriggerMock(
status: TestWorkflowStatus.Succeeded,
name: "test_req",
outputs: new MockOutput(content: new { customerEmail = (string)null })
);
2. Why the Workflow Definition Also Needs Updating
Even with a valid MockOutput, using direct equality checks like @equals(triggerBody()?['property'], null) can still fail in local unit test execution.
- Live Cloud Runtime: The engine performs implicit type coercion, often converting
null references in string-interpolated expressions to empty strings ("").
- Local Test Engine: Evaluates expressions strictly against the mock payload without implicit coercion, causing direct comparisons against
@null to fail when property navigation resolves to undefined.
The Recommended Solution
To make your condition robust across both live execution and local C# unit tests, replace direct null comparisons with the coalesce() or empty() functions.
References
From the Azure Logic Apps Workflow Definition Language / Function Reference:
"coalesce: Return the first non-null value from one or more parameters. Empty strings, empty arrays, and empty objects are not null."
From the Schema reference for workflow actions and triggers / Function Reference:
"empty: Check whether a collection is empty. Return true if the collection is empty, or return false if not empty."
How to Rewrite Your Workflow Condition
Instead of your current condition:
@equals(triggerBody()?['someProperty'], null)
Use coalesce() to safely intercept any null or missing values and provide a fallback string for comparison:
@equals(coalesce(triggerBody()?['someProperty'], 'NULL_FALLBACK'), 'NULL_FALLBACK')
By combining the coalesce() expression in your JSON definition with a valid new MockOutput(...) instantiation in your C# test script, your workflow will execute cleanly without internal server errors.
Please let me know if this resolves your issue.