【问题标题】:Mocked method returns null模拟方法返回 null
【发布时间】:2011-09-30 05:44:19
【问题描述】:

我的 Silverlight 项目中有一个简单的测试方法:

[TestMethod]
[Tag("User")]
public void ViewModel_NewUserAdded_DefaultCulturesLoaded()
{
    //setup
    Mock<INameService> mockNameService = new Mock<INameService>();
    MainViewModel viewModel = new MainViewModel();
    mockNameService
        .Setup(m => m.DefaultCultures(It.IsAny<Action<LoadOperation<kk_mp_name>>>()))
        .Returns(new Mock<OperationBase>(null).Object);
    viewModel.ContextName = mockNameService.Object;

    //action
    Messenger.Default.Send(-1, "New User Added");

    //verify
    mockNameService.Verify(
        (mo) => mo.DefaultCultures(It.IsAny<Action<LoadOperation<kk_mp_name>>>()),
        Times.Exactly(1));
}

DefaultCultures 方法总是返回 null 而不是新的模拟对象。 我做错了什么?

【问题讨论】:

  • Mock 将返回一个默认值(例如 null),以防发生未设置期望的调用。所以您能否检查调用是否按预期进行 - 例如如果参数不同,即不匹配约束。
  • 接口中的方法签名是:OperationBase DefaultCultures(Action&lt;LoadOperation&lt;kk_mp_name&gt;&gt; callback); 所以和It.IsAny&lt;Action&lt;LoadOperation&lt;kk_mp_name&gt;&gt;&gt;()太匹配了。只是你不能这样做......
  • = 试着让它成为一个严格的模拟......你应该得到一个更好的错误描述。因为如果调用没有明确的期望,它会抛出异常而不是返回 null。查看起订量文档,了解如何使其成为严格的模拟。
  • 不,这没有帮助。模拟创建时没有错误,但仍返回 null 而不是 object。

标签: .net silverlight unit-testing mocking moq


【解决方案1】:

Messenger.Default.Send 是否使用了您在viewModel.ContextName 上设置的模拟对象?如果您进入到您希望调用DefaultCultures 的代码,您可以检查ContextName 的具体类型以确保它是模拟实例。

我还发现在模拟设置上添加.Callback 很有帮助,可以在其上设置断点并确保正在调用该方法:

MainViewModel viewModel = new MainViewModel();
mockNameService
    .Setup(m => m.DefaultCultures(It.IsAny<Action<LoadOperation<kk_mp_name>>>()))
    .Callback((Action<LoadOperation<kk_mp_name>> a) =>
     {
         ; // Set breakpoint here
     })
    .Returns(new Mock<OperationBase>(null).Object);

【讨论】:

    【解决方案2】:

    从你的 cmets 来看,它看起来像

    var mockNameService = new Mock<INameService>(MockBehavior.Strict);
    

    没有太大帮助。

    所以我的下一个问题是问你为什么在这里传递 Null。

    new Mock<OperationBase>(null).Object
    

    你能发布 OperationBase 的代码吗?

    【讨论】:

    • OperationBaseSystem.ServiceModel.DomainServices.Client 命名空间中的一个简单抽象类。这里 null 是 OperationBase 的构造函数参数。如果我在调试中调用new Mock&lt;OperationBase&gt;(null).Object(通过 Debug Immediate 或 Quick Watch),那么我将获得实际的 OperationBase-mocked 实例,但在运行代码中我不是。从那里我猜测安装程序无法正常工作......
    • 如果我把它称为new Mock&lt;OperationBase&gt;(MockBehavior.Strict, null).Object 那么结果是一样的。
    猜你喜欢
    • 2020-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-19
    • 2019-07-27
    • 1970-01-01
    相关资源
    最近更新 更多