TL;DR
It's unclear what you're really trying to do.
If you have already defined the interface IFoo
(which is what your question seems to show) and you need to mock it to another type, you're already set: var bazz = new Bazz(new Mock<IFoo>());
If you have a concrete class Foo
that you haven't abstracted into an interface that you need to provide to another type as a dependency, then extracting an interface is one of the more common ways to allow the initialization of a Bazz
object without creating an actual Foo
class. Depending on what you're actual code looks like, you might limit scope by abstracting into IFoo
only the parts of Foo
that Bazz
depends on. The other way is to mock the concrete and provide moq with the constructor arguments to use. You'll need to make sure that the dependency parts of Foo
are "Mock-able" (public virtual) in order to provide the Mock with your setup and results.
Read More:
To answer the question of
how would the code look after the advice The best thing to do would be to ... Extract interface?
the advice to extract an interface may not be exactly what you're looking for. As it was mentioned in other answers, we are not sure what it is you are actually trying to test.
If you are trying to test functionality on the concrete Foo
implementation of IFoo
then extracting an interface and mocking IFoo
isn't really going to help you, because moq is going to implement the interface itself and only provide the "functionality" you tell it to provide in the setup methods and properties on that implementation. If this is what you are doing, AND the method under test calls some other method on the concrete Foo
implementation, AND that method is something you want to provide an abstraction for, then I would do as @Chris Marisic mentioned and change the method you desire to abstract to virtual
. With this as virtual you can use a mocking framework to provide the abstraction, or do as I have done in the past and create a sub type off the subject under test in the test class.
public class MyFooTests
{
... // Tests
private class SubFoo : Foo
{
public override void MethodToAbstract(bool par)
{
// do something expected
}
}
}
With this method you are still going to need to provide something to the constructor of Foo, but that would be a prime case for using mocks on those interfaces.
Now, if you are testing Foo
and the method under test is just calling methods on IBar
, IFizz
, IBuzz
, and there is no other abstraction you want to create, then you're already setup. Mock those interfaces, set them up to return what you expect in a particular test case, and provide Foo
with the mock objects.
The extract interface advice is really useful when your subject under test is dependent upon Foo, as mentioned by @Chris Marisic. However, I may not share his sentiment for not wanting to create interfaces in this situation. It depends on what smells more to you: creating an interface to provide mock-ability, or changing the modifier to provide the same. If you're going to change the modifier and still use moq to mock the concrete Foo
, you will need to either expose a default constructor (pretty smelly to me) or create the mock with the given constructor arguments specification, as mentioned in your referenced answer.
Lets say you have the following:
public class Baz
{
private Foo foo;
public Baz(Foo inputFoo)
{
this.foo = inputFoo;
}
public bool GetFromTheFoo()
{
// other stuff here
var fooStuff = this.foo.GetStuff();
// logic on the stuff;
return fooStuff != null;
}
}
In the above Baz
is dependent on Foo
. After extracting an interface of Foo
, Baz
would need to accept IFoo
.
Then Foo
would look like it does in your question and IFoo
would have a signature definition for the method you want to abstract away from Baz
.
object GetStuff();
Now, in your test you would still use var foo = new Mock<IFoo>();
and give foo
to your Baz
test subject. Don't forget to setup the IFoo.GetStuff()
method.
foo.Setup(f => f.GetStuff()).Returns(new object());
Because you have now created the IFoo
abstraction there is no need to
get around the constructor here?
because the mock of IFoo
only has a default constructor provided by moq.
Tangent
I personally prefer the interface approach, when it applies, because it removes indirect dependencies when testing. Let's say you have a class Baz
that depends on Foo
(not abstracted), but now Foo
has dependencies on Fizz
(or IFizz
like in your question) in its constructor.
class Fizz
{
}
class Foo // not abstracted : IFoo
{
private Fizz fizz;
public Foo(Fizz fizz)
{
this.fizz = fizz;
}
public object GetStuff()
{
return this.fizz;
}
}
class Baz
{
private Foo foo;
public Baz(Foo inputFoo)
{
this.foo = inputFoo;
}
public bool GetFromTheFoo()
{
// other stuff here
var fooStuff = this.foo.GetStuff();
// logic on the stuff;
return fooStuff != null;
}
}
Testing Baz
without an abstraction between Baz
and Foo
, would need to mock, stub, or create an actual Fizz
to get a testable instance of Foo
that we can give to the subject under test Baz
.
public void TestBaz()
{
var foo = new Foo(new Fizz());
var baz = new baz(foo);
var isFromBaz = baz.GetFromTheFoo();
}
Providing a controllable Fizz
may not always be easy, and can make your tests explode with complexity that may not be related to Baz
at all. But, if we have an IFoo
between Foo
and Baz
, then the indirect dependency Fizz
is removed because the ctor is an implementation detail, just like the actual functionality of IFoo.GetStuff
.
class Baz
{
private IFoo foo;
public Baz(IFoo inputFoo)
{
this.foo = inputFoo;
}
public bool GetFromTheFoo()
{
// other stuff here
var fooStuff = this.foo.GetStuff();
// logic on the stuff;
return fooStuff != null;
}
}
Then out test can just be:
public void TestBaz()
{
var foo = Mock.Of<IFoo>();
var baz = new baz(foo);
var isFromBaz = baz.GetFromTheFoo();
}
Some of this depends how you define a Unit that should be included in any given test. I try my best to make non-private methods the definition of a unit that needs testing, and if I can draw an abstracted-dependency line between one non-private making a call to another non-private, I do.