【问题标题】:How to mock specific methods and direct the rest of the methods to a particular implementation of the interface?如何模拟特定方法并将其余方法定向到接口的特定实现?
【发布时间】:2014-07-28 07:51:08
【问题描述】:

我有如下界面:

public interface IFoo
{
    int Prop1 { get; set; }
    string Prop2 { get; set; }
    string Method1();
    string Method2();
}

这是一个实现:

public class FooImplementation : IFoo
{
    public override int Prop1 { ... }
    public override string Prop2 { ... }
    public override string Method1() { ... }
    public override string Method2() { ... }
}

我想模拟Prop2Method2,对于其余的属性/方法,我想在实现中调用相应的属性/方法。除了描述性地为每个属性/方法提及Mock.Setup(..),是否有直接的方法来实现这一点?

我可以选择性地模拟属性和方法并将其余部分重定向到实现吗?

【问题讨论】:

  • new Mock<FooImplementation>() 不起作用吗?
  • 没有。我的FooImplementation 方法不是virtual。所以我不能嘲笑他们中的任何一个。
  • 这无关,但在您的示例中,Foo 被声明为一个接口。然而,名称和实现表明它是一个类。这是一个错误吗?
  • Foo 是一个接口。 FooImplementation 是一个类。
  • 应该是IFoo

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


【解决方案1】:

是的,Moq 有一个名为 CallBase 的属性。所以你可以这样做:

Mock<FooImplementation> mock = new Mock<FooImplementation>();
mock.CallBase = true;

如果你想要接口类型的Mock而不是具体的实现,可以使用Moq的As获取正确的类型:

Mock<Foo> mock = new Mock<FooImplementation>().As<Foo>();
mock.CallBase = true;

【讨论】:

  • 谢谢本!我对这个问题还有一个补充。如果Foo 是一个抽象类而不是一个接口呢? Mock.As 似乎只支持接口。有没有办法解决这个问题?
  • @Sornakumar 实际上,我认为As 对于您所描述的内容并不是绝对必要的。您是否尝试过第一个示例中的版本?
  • 是的。我无法模拟其中一种方法,因为FooImplementation 没有任何虚拟方法。
  • @Sornakumar 啊,你是对的。在那种情况下,恐怕我不知道是否或如何做到这一点。显而易见的解决方法是创建一个界面,如果可以的话。我还要说,必须这样做可能是代码异味。
  • 只是大声思考。这不是代码味道吗?当我们需要模拟接口的一些而不是所有方法时,它可以作为接口隔离的指针吗?该接口的实现最终会有多个改变的理由,因此可能会破坏单一责任原则?
猜你喜欢
  • 1970-01-01
  • 2017-05-29
  • 2015-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多