Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Moq:如何使用模拟对象作为另一个模拟对象的接口_C#_Asp.net_.net_Unit Testing_Moq - Fatal编程技术网

C# Moq:如何使用模拟对象作为另一个模拟对象的接口

C# Moq:如何使用模拟对象作为另一个模拟对象的接口,c#,asp.net,.net,unit-testing,moq,C#,Asp.net,.net,Unit Testing,Moq,上下文 我目前正在为我的ASP.NETWebAPI应用程序实施一些单元测试,为此我决定使用Moq作为模拟框架。这是一个我已经非常熟悉的工具,但我还不是它的专家 对于我的一些测试,我想模拟DbContext的行为。这适用于所有正常情况,但我想向其添加一个接口,并使用另一个模拟对象来设置DbContext在被强制转换到此接口时应该具有的行为(下面的代码可能更具解释性) 实施 // Create the mocked objects with the MockBehavior.Strict optio

上下文

我目前正在为我的ASP.NETWebAPI应用程序实施一些单元测试,为此我决定使用Moq作为模拟框架。这是一个我已经非常熟悉的工具,但我还不是它的专家

对于我的一些测试,我想模拟DbContext的行为。这适用于所有正常情况,但我想向其添加一个接口,并使用另一个模拟对象来设置DbContext在被强制转换到此接口时应该具有的行为(下面的代码可能更具解释性)

实施

// Create the mocked objects with the MockBehavior.Strict option
IPermissionContainer permissionContainer = MockedPermissionContainer().Object;
Mock<DbContext> dbContext = MockedAccountContext(expectedAccount);

// This is how I try to set my permissionContainer as the returned object when casting the DbContext to an IPermissionContainer
dbContext.As<IPermissionContainer>().SetReturnsDefault(permissionContainer);

// Both of these tests are working fine
Assert.IsAssignableFrom<IPermissionContainer>(dbContext.Object);
Assert.NotNull((IPermissionContainer)dbContext.Object);

// This first test accesses the permissionContainer directly and executes normally
var test1 = permissionContainer.GetUserPermissions(_cancellationTokenSource.Token, "Account", requestContext.Object);

// This second test try to access the permissionContainer that was setup earlier but it throws a Moq.MockException (see below)
var test2 = ((IPermissionContainer)dbContext.Object).GetUserPermissions(_cancellationTokenSource.Token, "Account", requestContext.Object);
//使用MockBehavior.Strict选项创建模拟对象
IPermissionContainer permissionContainer=MockedPermissionContainer().Object;
Mock dbContext=MockedAccountContext(expectedAccount);
//这就是在将DbContext强制转换为IPermissionContainer时,我如何尝试将permissionContainer设置为返回的对象
dbContext.As().SetReturnsDefault(permissionContainer);
//这两项测试都运行良好
Assert.IsAssignableFrom(dbContext.Object);
Assert.NotNull((IPermissionContainer)dbContext.Object);
//第一个测试直接访问permissionContainer并正常执行
var test1=permissionContainer.GetUserPermissions(_cancellationTokenSource.Token,“Account”,requestContext.Object);
//第二个测试尝试访问先前设置的permissionContainer,但它抛出Moq.MockException(见下文)
var test2=((IPermissionContainer)dbContext.Object).GetUserPermissions(_cancellationTokenSource.Token,“Account”,requestContext.Object);
Moq.MockException:IPermissionContaine.GetUserPermissions(System.Threading.CancellationToken,“Account”,Mock.Object)调用失败,模拟行为严格

模拟上的所有调用都必须有相应的设置

问题

异常表明GetUserPermissions方法设置不正确,即使第一次测试成功表明情况相反。因此,这可能意味着强制转换返回的对象不实现permissionContainer对象的行为,SetReturnsDefault()方法可能不返回传入的对象

我的问题是,我不知道SetReturnsDefault()在本例中是否正确使用(我尝试查看了和文档,但没有适用于此方法的内容)

如果它使用正确,那么它可能是一个bug,因此我可以在GitHub上打开一个问题,并以不同的方式模拟我的对象。 如果没有,那么您知道是否有方法将my permissionContainer用作DbContext上IPermissionContainer的实现吗?或者如果它是一个不推荐的实现


最后我知道单独模拟我的两个对象听起来可能很奇怪,但就我而言,我认为这可能会简化我的开发,节省我很多时间。此外,我想知道是我还是Moq在这种情况下表现不佳。

您是否在某处设置了GetUserPermissions?是的,它是在MockedPermissionContainer函数上设置的。否则,带有“test1”的行将失败。