Reputation: 66851
Using moq, if I try to mock a method directly on Foo
, I get this: Invalid verify on a non-virtual (overridable in VB) member.
My alternative is to mock IFoo
, which gets rid of the above problem, but then I can't construct it because Foo
does not have a paramaterless constructor (Constructor arguments cannot be passed for interface mocks.
). What can I do?
Upvotes: 8
Views: 6133
Reputation: 28016
You should be able to mock IFoo without problem, and you would have no reason to pass arguments when you are mocking an interface. Your IFoo mock will be exactly that (a mock!), and will have no knowledge of Foo or any real implementation, so passing constructor arguments would not make sense.
Edit: I would add that mocking an interface if one exists is almost always preferable to mocking a concrete implemention. If you only have a concrete implementation, the fact that you want to mock it probably means it would be a good candidate for adding an interface.
Upvotes: 7
Reputation: 4833
Moq creates a proxy-object which requires that all your mocked methods are overridable and your class is not sealed. So you can mark your method as virtual.
The code below works fine:
public interface IFoo
{
int Test(int myParameter);
int TestInternal(int myParameter);
}
public class Foo : IFoo
{
private int _someConstructorArgument;
public Foo(int someConstructorArgument)
{
_someConstructorArgument = someConstructorArgument;
}
public virtual int Test(int myParameter)
{
return _someConstructorArgument + TestInternal(myParameter);
}
public virtual int TestInternal(int myParameter)
{
return myParameter;
}
}
public class Program
{
static void Main(string[] args)
{
var mock = new Mock<Foo>(MockBehavior.Loose, 50);
mock.Setup(x => x.TestInternal(100))
.Returns(200);
mock.CallBase = true;
Console.WriteLine(mock.Object.Test(100));
Console.ReadLine();
}
}
Upvotes: 0