I have a failing test in NSubstitute because a parameter passed in to a substituted call does not match. Here is the relevant code that is being tested:
// Arrange
PermissionsProviderSub = Substitute.For<IPermissionsProvider>();
MenuDataProviderSub = Substitute.For<IMenuDataProvider>();
PermissionsProviderSub.GetPermissions(UserId).Returns(ExpectedUserPermissions);
MenuDataProviderSub.GetMenuData(ExpectedUserPermissions.AuthorisedPageIds).Returns(Arg.Any<IList<BusinessFocusArea>>());
var sut = new MenuViewModelFactory(MenuDataProviderSub, PermissionsProviderSub);
// Act
var result = sut.Create();
// Assert
MenuDataProviderSub.Received().GetMenuData(ExpectedUserPermissions.AuthorisedPageIds);
The problem occurs in the ExpectedUserPermissions.AuthorisedPageIds
property, which looks like this:
public IEnumerable<string> AuthorisedPageIds
{
get
{
return ApplicationPagePermissions != null ?
ApplicationPagePermissions.Select(permissionSet => permissionSet.PageId) :
Enumerable.Empty<string>();
}
}
As you can see, there is a LINQ Select, which is extracting the PageId
property from within the ApplicationPagePermissions
collection and returning it as an IEnumerable<string>
. Because the projection within that property creates a new object, the substitution does not match, as it sees the 2 objects as being different.
Can I create a callback on the parameter passed in to GetMenuData
so that I can examine the value of it?
The documentation on NSubstitute callbacks only talks about examining the return value from a call, rather than a parameter passed into the call.
Typical. As soon as I post to SO, the answer presents itself. Rather than expecting a specific object when creating the substitute call, I expect any instance of type IEnumerable<string>
and create a callback when checking the Received()
call that actually verifies the values. The substitute call becomes this:
MenuDataProviderSub.GetMenuData(Arg.Any<IEnumerable<string>>()).Returns(Arg.Any<IList<BusinessFocusArea>>());
The Received()
check becomes this:
MenuDataProviderSub.Received().GetMenuData(Arg.Is<IEnumerable<string>>(a => VerifyPageIds(ExpectedUserPermissions.AuthorisedPageIds, a)));
private static bool VerifyPageIds(IEnumerable<string> expected, IEnumerable<string> actual)
{
var expectedIds = expected.ToList();
var actualIds = actual.ToList();
return expectedIds.Count == actualIds.Count && expectedIds.All(actualIds.Contains);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With