UniTask enables us to cleanly use async/await syntax within Unity. Testing code that uses UniTask requires that we use Unity Test Framework and run the tests from within a [UnityTest]. The recommended syntax for this is:
[UnityTest]
public IEnumerator MyFunctionDoesWhatIExpect() => UniTask.ToCoroutine(async () =>
{
MyType result = await SomeFunctionThatReturnsAUniTask();
result.SomeProperty.Should().Be(theValueIExpect); // yay FluentAssertions!
});
But what if we want to run the same test with different input parameters? We don’t want to just duplicate the same code in every test; that would be a maintenance nightmare. NUnit solves this nicely with the [TestCase] attribute.
Unity Test Framework’s [UnityTest] attribute does not support an equivalent to NUnit’s [TestCase] attribute for parameterized tests.
But, it does support the [ValueSource] attribute. While not nearly as clean, we can get some basic parameterized testing using something like this:
private static readonly (string input, string expectedOutput)[] InputsAndExpectedOutputs =
{
(null,""),
("a name", "a name"),
("remove special characters !@#$%^&*()[]", "remove special characters"),
};
[UnityTest]
public IEnumerator MyStringFunctionDoesWhatIExpect(
[ValueSource(nameof(InputsAndExpectedOutputs))](string input, string expectedOutput) ioPair
) => UniTask.ToCoroutine(async () =>
{
var result = await MyUniTaskStringFunction(ioPair.input);
result.Should().BeEquivalentTo(ioPair.expectedOutput);
});
It’s pretty ugly, but it works!
For more information on what you can do with [ValueSource], check out this tutorial