Reputation: 458
I have a class
public class Foo
{
public Foo(IBar bar)
{
//...
}
public virtual int GetValue(){}
public virtual DoActual()
{
...
var value = GetValue();
...
}
}
I need to test it. I want to override GetValue method and return particular value to caller. Here is my test code:
[TestMethod]
public void Test()
{
var mock = new Mock<Foo>{ CallBase=true}; // problem is here
mock.Setup(x=>x.GetValue()).Returns(1);
mock.DoActual();
//asserts
}
Since my Foo class constructor has dependencies, I have to pass it into object initializer. Moq offers to pass arguments to params[] overload:
[TestMethod]
public void Test()
{
var barMock= new Mock<IBar>();
var mock = new Mock<Foo>(barMock){ CallBase=true}; // problem is still here
mock.Setup(x=>x.GetValue()).Returns(1);
mock.DoActual();
//asserts
}
When I pass my mock this way, I got error saying that Moq.Mock`1[IBar] is not that constructor of Foo accepting.
When I pass barMock.Object to constructor I get basically same error with different type:
"Could not find a constructor that would match given arguments:
Castle.Proxies.IBarProxy"
I stuck in this place and don't know how to resolve my Foo class dependencies.
Upvotes: 4
Views: 5268
Reputation: 10839
Your minimised problem above doesn't compile, which suggests that you haven't tested it in it's current form. This makes it hard to tell if your actual issue is being correctly described or if you have reduced the problem too far and removed your actual problem, in which case you may want to edit your question to include additional details. The following code, based on the above compiles and works.
public interface IBar {
}
public class Foo
{
public Foo(IBar bar)
{
//...
}
public virtual int GetValue(){ return 0;}
public virtual void DoActual()
{
var value = GetValue();
}
}
[TestFixture]
public class SomeTests {
[Test]
public void TestMethodCalled() {
var barMock = new Mock<IBar>();
var mock = new Mock<Foo>(barMock.Object) { CallBase = true };
mock.Setup(x => x.GetValue()).Returns(1);
mock.Object.DoActual();
//asserts
mock.Verify(x => x.GetValue());
}
}
It passes barMock.Object
into the constructor, and verifies that the method has been called.
As has already been said, mocking the class you're testing is generally a bad idea, a better approach would be to manipulate/mock the dependencies of GetValue
so that it returns the result you're after. Obviously your ability to do this will depend on what the method does and how much code you can change if necessary and sometimes, particularly with legacy code you just have to work with what you've got.
Upvotes: 6
Reputation: 914
In general you should create mocks of the dependencies of the class that you want to test (system under test, SUT), not of SUT itself.
I'd suggest creating the following
public class FooForTest : Foo
{
public FooForTest(IBar bar) : base(bar) {}
public override int GetValue() { return 1; }
}
Then new FooForTest(barMock.Object)
should work.
Upvotes: 0