Microsoft Fakes支持抽象方法吗?

本文关键字:抽象方法 支持 Fakes Microsoft | 更新日期: 2023-09-27 18:07:23

我有一个类设置如下:

public abstract FooClass {
    public FooClass() {
        // init stuff;
    }
    public void RandomMethod() {
        // do stuff;
    }
    public abstract WhatIWantToShim();
}

我要做的是在ShimFooClass上设置WhatIWantToShim,像这样:

ShimFooClass.AllInstances.WhatIWantToShim = () => Boo();

我可以很好地设置RandomMethod

ShimFooClass.AllInstances.RandomMethod = () => CalculatePi();

然而,似乎生成的ShimFooClass并没有在ShimFooClass的AllInstances属性上创建WhatIWantToShim属性。

我已经看了http://msdn.microsoft.com/en-us/library/hh549176.aspx#bkmk_shim_basics,但我没有看到任何关于抽象方法。我看到的唯一不支持的东西是finalizer。有人知道这是怎么回事,这种情况是否成立吗?

Microsoft Fakes支持抽象方法吗?

Ahhh....bummer

接口和抽象方法存根提供了可以在测试中使用的接口和抽象方法的实现。Shims不能仪表接口和抽象方法,因为它们没有方法体。

http://msdn.microsoft.com/en-us/library/hh549175 (v = vs.110) . aspx

更新:可以做什么,虽然是存根垫片。

using (ShimsContext.Create())
{
    bool wasAbstractMethodCalled = false;
    var targetStub = new StubFooClass()
    {
        WhatIWantToShim01 = () => wasAbstractMethodCalled = true
    };
    var targetShim = new ShimFooClass(targetStub);
    targetShim.AllInstances.RandomMethod = () => CalculatePi();
    FooClass  target = targetShim.Instance;
    target.WhatIWantToShim();
    Assert.IsTrue(wasAbstractMethodCalled, "The WhatIWantToShim method was not called.");
}

由于shim不能处理绕道WhatIWantToShim方法,而存根可以,因此只需创建一个存根类的新实例并为抽象方法设置绕道处理程序。(注意:在我的实际代码中生成Fakes时,在WhatIWantToShim末尾标记的01是为我自动添加的)

然后将实例化的存根传递给shim类的构造函数,并根据需要删除。

我在这里回答,因为我很确定另一个答案没有回答这个问题,以便将来的搜索返回有用的信息。

首先,你不能填充接口。抽象方法相当于接口。而且,没有理由……

{
    bool wasAbstractMethodCalled = false;
    var targetStub = new StubFooClass()
    {
        WhatIWantToShim01 = () => wasAbstractMethodCalled = true
    };
    ShimFooClass.AllInstances.RandomMethod = @class => targetStub.CalculatePi();
    targetStub.WhatIWantToShim();
    Assert.IsTrue(wasAbstractMethodCalled, "The WhatIWantToShim method was not called.");
}

以上是前一个答案的简化版本,将简单地调用您刚刚分配的操作。这可能不是你的本意。

记住你为什么游泳。当您希望在测试的方法中避免方法调用的影响时,您需要谨慎。抽象方法可以没有主体,因此不能影响任何东西。这唯一有用的时候是在子类中,在子类中,您首先可以使用shim。

唯一可能出现问题的情况是,如果第三个类秘密地持有抽象类的实例并使用子类对其进行实例化。你装不出来的。然而,这是一个可怕的设计;该实例应该来自某个方法(您可以填充)或传入(因为DI是一件好事!),否则抽象就毫无价值,并且您还可以将实例声明为子类型,因为您没有以任何方式使用抽象。