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

时间:2017-05-31 01:35:48

标签: c# asp.net .net unit-testing moq

上下文

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

对于我的一些测试,我想模拟DbContext的行为。这适用于所有正常情况,但后来我想为它添加一个接口,并使用另一个模拟对象来设置我的DbContext在将其转换为此接口时应具有的行为(下面的代码可能更具说明性)。 / p>

实施

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

Moq.MockException:IPermissionContaine.GetUserPermissions(System.Threading.CancellationToken,&#34; Account&#34;,Mock.Object)调用因模拟行为严格而失败。

     

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

问题

异常表示GetUserPermissions方法未正确设置,即使第一次测试成功表明相反。所以这可能意味着强制转换返回的对象没有实现permissionContainer对象的行为,并且SetReturnsDefault()方法可能不会返回传入的对象。

我的问题是我不知道在这种情况下是否正确使用了SetReturnsDefault()(我试图查看QuickstartAPI文档,但没有任何内容这种方法有。)

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

终于我知道单独模仿我的两个对象可能听起来很奇怪,但在我的情况下,我认为它可以减轻我的开发并节省我很多时间。此外,我有兴趣知道我或Moq在这种情况下表现不佳。

0 个答案:

没有答案