为什么这个Machine.Fakes参数匹配抛出异常?

时间:2012-11-22 16:31:26

标签: mspec machine.fakes

我正在使用Machine.Fakes.NSubstitute并想要“伪造”返回值,这样如果输入参数与特定值匹配,则返回模拟对象,否则返回null。

我尝试了以下内容:

host.WhenToldTo(h => h.GetTenantInstance(Param.Is(new Uri("http://foo.bar"))))
    .Return(new TenantInstance());

但它引发了以下异常:

  

System.InvalidCastException:无法转换类型的对象   输入'System.Linq.Expressions.NewExpression'   'System.Linq.Expressions.ConstantExpression'。

我目前的解决方法是执行以下操作:

host.WhenToldTo(h => h.GetTenantInstance(Param.IsAny<Uri>()))
    .Return<Uri>(uri => uri.Host == "foo.bar" ? new TenantInstance() : null);

哪个有点臭。

1 个答案:

答案 0 :(得分:3)

我在这里看到三个方面:

  1. 当在模拟对象上调用具有引用类型返回值的方法并且没有为该调用设置任何行为时,模拟对象将返回模拟。如果您希望它返回null,则必须明确配置它。因此,设置

    是不够的
    host.WhenToldTo(h => h.GetTenantInstance(Param.Is(new Uri("http://foo.bar"))))
        .Return(new TenantInstance());
    

    您还必须使用以下内容设置其他案例:

    host.WhenToldTo(h => h.GetTenantInstance(Param<Uri>.Matches(x => !x.Equals(new Uri("http://foo.bar")))))
        .Return((TenantInstance)null);
    

    我发现您的“解决方法”解决方案比这两种设置更优雅。

  2. 当您将方法调用参数与相等性匹配时,无需使用Param.Is() 。您只需使用

    设置行为即可
    host.WhenToldTo(h => h.GetTenantInstance(new Uri("http://foo.bar")))
        .Return(new TenantInstance());
    
  3. 使用Param.Is()时遇到异常的事实是Machine.Fakes 的缺点。我不明白为什么这不起作用。我会在某个时候纠正这个问题并告诉你。