How to mock class members in C#?
I'm trying to use FakeItEasy to mock an object that is a member of a C# class I'm creating.
The FakeItEasy documentation indicates that you fake an object in a way similar to this:
private static var m_physics = A.Fake<IPhysics>();
That is, using the "var" keyword.
However, in this case the C# compiler doesn't 开发者_如何学Golike the fact that var is being used in a non-local context. I get this error:
The contextual keyword 'var' may only appear within a local variable declaration
Can't I mock an object that's not local?
I think you're missing the point of mocks/stubs. Mocks and stubs are used for testing when you don't want the subject under test to pass or fail depending on other components that it depends on. So what you do is swap explicit implementations of these out for mocks/stubs of these dependencies that you can completely control within the test.
class Foo {
public Foo(IBar bar) { }
public object M() { // do something with IBar }
}
Here Foo
has a dependency on IBar
. We want to test Foo.M
. We don't want the test to pass or fail based on whether or not the concrete implementation that we give to Foo
of IBar
is working or not.
[Fact]
public void MDoesWhatItIsSupposeToDo() {
var foo = new Foo(new Bar());
object expected = // expected result
Assert.Equal(expected, foo.M());
}
If Bar
is broken this test could fail even though Foo
might be coded perfectly correctly. So you sub in a mock/stub to preven this
[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());
}
Now this test only passes or fails if Foo
is coded correctly or not, independently of whether or not your concrete implementations of IBar
are correct.
This is the point of mocks.
So all of this is to say, you are not using mocks properly.
Can't I mock an object that's not local?
You can, but not in the way that you are doing. First, fields can't be implicitly typed. Secondly, you don't mock the field explicitly like you've done. Instead you do it like this:
class Whatever {
private IPhysics m_physics;
public Whatever(IPhsyics physics) { this.m_physics = physics; }
}
Then:
var physics = A.Fake<IPhysics>();
var whatever = new Whatever(physics);
You can only use the 'var' keyword in a local context like a function block. You cannot declare a class member as a 'var'.
精彩评论