2013-04-04 70 views
5

我有以下方式一类的设置:微软是否支持垫片上的抽象方法?

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

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

    public abstract WhatIWantToShim(); 
} 

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

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但我没有看到关于抽象方法的任何内容。我看到的唯一不支持的东西是终结器。有人知道这里发生了什么,如果这种情况得到支持?

+0

你可以创建一个方法来设置属性? – RedJandal 2013-04-04 22:54:09

+0

没有关注你,在shim类中创建的抽象方法没有属性。那就是问题所在。 – 2013-04-05 19:17:13

回答

4

唉唉....无赖

接口和抽象方法。存根提供了可用于测试的接口和抽象方法的实现。 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."); 
} 

由于垫片不能处理的迂回方法WhatIWantToShim和存根可以,只需要创建存根类的新实例,并设置迂回处理程序抽象方法。 (注意:在我的实际代码中生成Fakes时,会自动为我添加WhatIWantToShim结尾的01标记)。

然后只是将实例化的存根传递给填充类的构造函数并根据需要填充。

0

我在这里回答,因为我很确定其他答案没有回答这个问题,所以以后的搜索将返回有用的信息。

首先,您无法填充接口。抽象方法相当于一个接口。此外,没有理由。

{ 
    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是一件好事!),否则抽象是毫无价值的,你也可以将实例声明为子类型,因为你没有以任何方式使用抽象。