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

时间:2013-02-22 14:27:55

标签: c# unit-testing callback mocking 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);

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

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

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

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

NSubstitute callbacks上的文档仅讨论检查调用的返回值,而不是传递给调用的参数。

1 个答案:

答案 0 :(得分:6)

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

MenuDataProviderSub.GetMenuData(Arg.Any<IEnumerable<string>>()).Returns(Arg.Any<IList<BusinessFocusArea>>());            

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);
}