通过NSubstitute中的回调验证调用参数

lev*_*nis 5 c# unit-testing mocking callback nsubstitute

我在NSubstitute中有一个失败的测试,因为传入替换调用的参数不匹配.以下是正在测试的相关代码:

// 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);
Run Code Online (Sandbox Code Playgroud)

ExpectedUserPermissions.AuthorisedPageIds属性中出现问题,如下所示:

public IEnumerable<string> AuthorisedPageIds
{
    get
    {
        return ApplicationPagePermissions != null ? 
            ApplicationPagePermissions.Select(permissionSet => permissionSet.PageId) :
            Enumerable.Empty<string>();
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,有一个LINQ Select,它PageIdApplicationPagePermissions集合中提取属性并将其作为一个返回IEnumerable<string>.因为该属性中的投影创建了一个新对象,所以替换不匹配,因为它将两个对象视为不同.

我可以在传入的参数上创建回调,GetMenuData以便我可以检查它的值吗?

关于NSubstitute回调的文档仅讨论检查调用的返回值,而不是传递给调用的参数.

lev*_*nis 6

典型.一旦我发布到SO,答案就出现了.在创建替换调用时,我期望任何类型的实例,IEnumerable<string>并在检查Received()实际验证值的调用时创建回调,而不是期望特定对象.替代电话变为:

MenuDataProviderSub.GetMenuData(Arg.Any<IEnumerable<string>>()).Returns(Arg.Any<IList<BusinessFocusArea>>());            
Run Code Online (Sandbox Code Playgroud)

Received()检查成为本:

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);
}
Run Code Online (Sandbox Code Playgroud)