Custom APIs are ever more popular in Power Platform. They allow you to convert reusable logic into APIs and expose them as part of the SDK and Web API. You can call them from front-end, back-end, apps, flows, and even external systems can call them.
You can call Custom APIs by POST (Actions) or GET (Functions) messages. When calling them as POST, you send a JSON payload. The JSON payload gets converted to Input parameters. Each parameter can be of primitive type, Entity, or EntityCollection.
I’m sure you will write enough unit tests to test every aspect of your API in any possible scenario, but chances are you will get bug reports and to make sure these pesky bugs never happen again, you will add a unit test for each of them. When doing so, you will have to write some code like the following for the sample JSON that has been shared with you.
[TestMethod]
public void Execute_GivenPidAndExistingContactBucket_ReturnsExpectedOutput()
{
// Arrange
var pluginContext = _context.GetDefaultPluginContext();
pluginContext.InputParameters = new ParameterCollection
{
["id"] = _contact.bpg_Pid,
["firstName"] = "Reza",
["lastName"] = "Niroomand",
["consents"] = new EntityCollection(
new Entity[]
{
new Entity("Consent")
{
["consentLevel"] = 0,
["lastUpdatedOn"] = "",
["userSelection"] = "1",
["applicationName"] = "",
},
// reduced for brevity
})
};
// Act
_context.ExecutePluginWith<PostContactApiPlugin>(pluginContext);
// Assert
using (new AssertionScope("Api Response"))
{
pluginContext.OutputParameters.Should().HaveCount(2).And.ContainKeys("status", "data");
pluginContext.OutputParameters["status"].As<int>().Should().Be(11012);
pluginContext.OutputParameters["data"].As<string>().Should().StartWith("User record updated");
}
// reduced for brevity
}
Wouldn’t it be easier if you could just copy and past the JSON sample that’s been shared with you? Unfortunately the serializer that the product team is using has not been shared with us in the SDK, but writing one is not difficult. Here you are.
https://gist.github.com/rezanid/855d85d1b14268d4a6f41ec0def3a4e7.jsTo use these converters, you just need to create an instance of SerializationSettings when you setup your test class, like the following example.
[TestInitialize]
public void Setup()
{
_serializerSettings = new JsonSerializerSettings();
_serializerSettings.Converters.Add(new ParameterCollectionJsonConverter());
_serializerSettings.Converters.Add(new EntityJsonConverter());
_serializerSettings.Converters.Add(new EntityCollectionJsonConverter());
}
And now we can write our test method using the JSON payload as is.
[TestMethod]
public void Execute_GivenPidAndExistingContactBucket_ReturnsExpectedOutput()
{
// Arrange
var pluginContext = _context.GetDefaultPluginContext();
pluginContext.InputParameters = JsonConvert.DeserializeObject<ParameterCollection>(
"""
{
"id" = _contact.bpg_Pid,
"firstName": "Reza",
"lastName": "Niroomand",
"consents":
{
{
"consentLevel": 0,
"lastUpdatedOn": "",
"userSelection": "1",
"applicationName": "",
},
// reduced for brevity
})
}
""", _serializerSettings);
// Act
_context.ExecutePluginWith<PostContactApiPlugin>(pluginContext);
// Assert
using (new AssertionScope("Api Response"))
{
pluginContext.OutputParameters.Should().HaveCount(2).And.ContainKeys("status", "data");
pluginContext.OutputParameters["status"].As<int>().Should().Be(11012);
pluginContext.OutputParameters["data"].As<string>().Should().StartWith("User record updated");
}
// reduced for brevity
}
It makes your unit tests easier to write (and read) and more similar to the actual data shared with you. There is also less code to write. What’s not to like?!
Leave a Reply