2011-05-11 87 views
0

我正在尝试使用FakeItEasy来模拟一个对象,该对象是我创建的C#类的成员。如何在C#中模拟类成员?

的FakeItEasy文档表明您与此类似的方式伪造的对象:

private static var m_physics = A.Fake<IPhysics>(); 

也就是说,使用“无功”的关键字。

但是,在这种情况下,C#编译器不喜欢在非本地上下文中使用var这一事实。我得到这个错误:

上下文关键字“变种”只能出现在局部变量声明

内我不能嘲笑的对象,这不是地方?

+3

我想你混淆了隐式类型嘲讽。如果将'var'更改为返回的实际类型,则不会有问题。 – Tejs 2011-05-11 17:12:06

+0

嘲笑班级成员是如此不好... – pixelbobby 2011-05-11 17:12:35

+0

该类型还不存在。因此,需要模拟。 – Buggieboy 2011-05-11 17:15:27

回答

6

我认为你错过了嘲笑/存根(stub)这一点。当不希望被测主题通过或失败时,模拟和存根用于测试,具体取决于它所依赖的其他组件。因此,你所做的是将这些显式实现交换出来,以便在测试中完全控制这些依赖关系的模拟/存根。

class Foo { 
    public Foo(IBar bar) { } 
    public object M() { // do something with IBar } 
} 

这里FooIBar的依赖。我们想测试Foo.M。我们不希望测试通过或失败,这取决于我们对FooIBar的具体实施是否有效。

[Fact] 
public void MDoesWhatItIsSupposeToDo() { 
    var foo = new Foo(new Bar()); 
    object expected = // expected result 
    Assert.Equal(expected, foo.M()); 
} 

如果Bar被打破了这一测试可能失败,即使Foo可能完全正确编码。所以,你在一个模拟/存根Sub要防止措施这一

[Fact] 
public void MDoesWhatItIsSupposeToDo() { 
    var bar = A.Fake<IBar>(); 
    // set up bar to do what is expected of IBars 
    var foo = new Foo(bar); 
    object expected = // expected result 
    Assert.Equal(expected, foo.M()); 
} 

现在这个测试只传递或者Foo正确与否编码,独立于你的IBar具体的实现是否是正确的失败。

这是嘲笑的地方。

所以所有这一切都是说,你没有正确使用模拟。

Can't I mock an object that's not local?

你可以,但不是你所做的。首先,字段不能被隐式输入。其次,你不要像你所做的那样明确地嘲笑这个领域。相反,你不喜欢这样写道:

class Whatever { 
    private IPhysics m_physics; 

    public Whatever(IPhsyics physics) { this.m_physics = physics; } 
} 

然后:

var physics = A.Fake<IPhysics>(); 
var whatever = new Whatever(physics); 
+1

+1很好的广义解释! – 2011-05-11 17:33:01

+0

好的,这是一个很好的总结。谢谢。这并不是因为我错过了mock的观点,因为我想用现有的机制(mocks)来编译A类,当A包含B的实例并且B尚未实现时。上面包含的最后一点似乎给了我一个这样做的方法。 – Buggieboy 2011-05-11 17:40:46

+1

@Buggieboy:但这就是为什么你对接口('IPhysics')进行编码而不是具体的实现。这个问题与嘲笑无关。 – jason 2011-05-11 18:08:03

0

只能在本地环境中使用'var'关键字,如功能块。您不能将类成员声明为“var”。

+0

对。这就是错误信息所说的。这就是由于这个限制导致如何使用模拟框架的问题。 – Buggieboy 2011-05-11 17:29:42