This is a migrated thread and some comments may be shown as answers.

Recursive AutoMocking? Ninject interaction?

3 Answers 91 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Micah
Top achievements
Rank 1
Micah asked on 17 Jul 2014, 07:46 PM
01.public class Foo
02.{
03.    public Bar Bar;
04. 
05.    public Foo(Bar bar)
06.    {
07.        Bar = bar;
08.    }
09.}
10. 
11.public class Bar
12.{
13.    public IBaz Baz;
14. 
15.    public Bar(IBaz baz)
16.    {
17.        Baz = baz;
18.    }
19.}
20. 
21.public interface IBaz
22.{
23.    String GetString();
24.}
25. 
26.[Test]
27.public void when()
28.{
29.    var foo = new MockingContainer<Foo>();
30.    foo.Arrange<IBaz>(baz => baz.GetString()).Returns("Rawr!");
31. 
32.    var actualResult = foo.Instance.Bar.Baz.GetString();
33. 
34.    Assert.AreEqual("Rawr!", actualResult);
35.}

Given the above code, a null reference exception is thrown on line 32.

I am using NInject to do constructor dependency injection.  I have a large hierarchy of classes that take in their dependencies in their constructors as Foo and Bar do above.  I want all of my concrete classes to be instantiated and only have the interfaces get mocked.  In the above example, I want a real Bar constructed and a real Foo constructed but I want IBaz to be mocked.

I am aware that in the above scenario I could just manually construct a Foo, passing in a manually constructed Bar, but in my scenario, the dependency hierarchy is large and complex and interfaces wrap all external (not my code calls).  Is there an easy way to tell the MockingContainer<Foo> that it should mock all interfaces but not mock any concrete classes (actually instantiate them).

As I said, I am using Ninject to instantiate my classes and it does the right thing everywhere.  I understand that the automocking container is backed by Ninject.  Is there a way I can bind certain interfaces/classes to JustMock?  In the above example I could do something like:

kernel.Bind<IBaz>().To<Mock<IBaz>>()?  That way I could just use Ninject to instantiate my object hierarchy, but tell it which interfaces I want it to bind to JustMock mocked instances.

3 Answers, 1 is accepted

Sort by
0
Micah
Top achievements
Rank 1
answered on 17 Jul 2014, 07:49 PM
A little more spelunking and I found that I could do this:

public class Foo
{
    public Bar Bar;
 
    public Foo(Bar bar)
    {
        Bar = bar;
    }
}
 
public class Bar
{
    public IBaz Baz;
 
    public Bar(IBaz baz)
    {
        Baz = baz;
    }
}
 
public interface IBaz
{
    String GetString();
}
 
[Test]
public void when()
{
    var foo = new MockingContainer<Foo>();
    foo.Bind<Bar>().To<Bar>();
    foo.Arrange<IBaz>(baz => baz.GetString()).Returns("Rawr!");
 
    var actualResult = foo.Instance.Bar.Baz.GetString();
 
    Assert.AreEqual("Rawr!", actualResult);
}

This causes a real Bar to be constructed, while still mocking everything else.  This will unblock me, but it still requires me to manually go through and bind all of my concrete classes to themselves.  I would still like a way to tell JustMock to only mock interfaces, never concrete classes.
0
Micah
Top achievements
Rank 1
answered on 17 Jul 2014, 07:56 PM
Another note to future searchers:
foo.Bind<Bar>().ToSelf()
That will cause foo to instantiate the real Bar, just like in my previous post and I believe it is a little more clear to the reader.
0
Stefan
Telerik team
answered on 18 Jul 2014, 06:39 AM
Hello Micah,

MockingContainer will always instantiate a mock for every dependency, unless there is an explicit binding telling it to do otherwise.

container.Bind<T>().ToSelf()
is indeed the correct way to tell it to not create a mock for T.

Regards,
Stefan
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
General Discussions
Asked by
Micah
Top achievements
Rank 1
Answers by
Micah
Top achievements
Rank 1
Stefan
Telerik team
Share this question
or