C# Microsoft Fakes是否支持垫片上的抽象方法?

C# Microsoft Fakes是否支持垫片上的抽象方法?,c#,abstract,microsoft-fakes,C#,Abstract,Microsoft Fakes,我的课程设置如下所示: public abstract FooClass { public FooClass() { // init stuff; } public void RandomMethod() { // do stuff; } public abstract WhatIWantToShim(); } 我要做的是在ShimFooClass上设置WhatIWantToShim,如下所示: ShimFooClas

我的课程设置如下所示:

public abstract FooClass {
    public FooClass() {
        // init stuff;
    }

    public void RandomMethod() {
        // do stuff;
    }

    public abstract WhatIWantToShim();
}
我要做的是在ShimFooClass上设置WhatIWantToShim,如下所示:

ShimFooClass.AllInstances.WhatIWantToShim = () => Boo();
我可以很好地设置随机方法

ShimFooClass.AllInstances.RandomMethod = () => CalculatePi();
但是,生成的ShimFooClass似乎没有在ShimFooClass的AllInstances属性上创建WhatIWantToShim属性

我已经看过了,但是我没有看到任何关于抽象方法的东西。我看到的唯一不受支持的引用是终结器。有人知道这里发生了什么,以及这个场景是否得到支持吗?

啊哈……真糟糕

接口和抽象方法。存根提供了可用于测试的接口和抽象方法的实现。垫片不能为接口和抽象方法提供工具,因为它们没有方法体

更新:但是可以做的是短接垫片

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方法的迂回,而存根可以,因此只需创建存根类的新实例并为抽象方法设置迂回处理程序。(注意: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.");
}
以上是先前答案的简化版本,将简单地调用您刚才分配的操作。这可能不是你的意图

记住你为什么这么做。当您想要避免正在测试的方法中的方法调用的影响时,可以使用垫片。抽象方法可以没有主体,因此不能影响任何东西。唯一有用的时候是在子类中,首先可以使用垫片


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

您能创建一个设置属性的方法吗?不遵循您的要求,在shim类上创建的抽象方法没有属性。这就是问题所在。