chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
I am trying to swap any object that implements a certain Interface.
Isolate.Swap.NextInstance<IContentService>().With(fakeContentProcess);
But I am getting Cannot type mock Interfaces or Abstract classes exception. Is there any workaround for this?

Thanks.
asked by sony (7.2k points)

5 Answers

0 votes
Hi Sony,

Currently there's no way to do it :(
Can you please tell me why do you need it? Is it a case where you have few types that are implementing the same interface?
answered by ohad (35.4k points)
0 votes
Hi Ohad

We are using IoC/DI pattern (Ninject) in our application. For this we need interface of the class. Some how we are creating object of that interface using Kernel.Get provided by Ninject. With the object of that interface, we are calling some method of it.

Suppose we have a method to test, in which we are creating object of interface and calling its method. Now we want to test that method and mock that interface method for testing. So we need to swap that interface object with its fake object when ever next instance will be created of that interface.

Kindly let us know how can we achieve this. Thanks
answered by sony (7.2k points)
0 votes
Hi Sony,

In that case you can still fake the concrete class and ninject will return an instance of the the faked concrete class.

Simple example:
public interface IFoo
{
    int Bar();
}

public class Foo : IFoo
{
    public int Bar()
    {
        return 1;
    }
}

public class UnderTest
{
    private IFoo foo;

    public int UseFoo()
    {
        using (IKernel kernel = new StandardKernel())
        {
            kernel.Bind<IFoo>().To<Foo>();
            foo = kernel.Get<IFoo>();
        }

        return foo.Bar();
    }
}

[TestFixture]
public class Tests
{
    [Test]
    public void Test()
    {
        Foo fake = Isolate.Fake.Instance<Foo>();
        Isolate.WhenCalled(() => fake.Bar()).WillReturn(5);
        Isolate.Swap.NextInstance<Foo>().With(fake);

        UnderTest ut = new UnderTest();
        var result = ut.UseFoo();
        Assert.AreEqual(5, result);
    }
}


In the test above you can see that ninject returned a faked instance of Foo.
answered by ohad (35.4k points)
0 votes
Hi Ohad,

Thanks for your reply. But I am still getting error while executing test case for this. We have code something like :

public interface IFoo
{
int Bar();
}

public class Foo : IFoo
{

public Foo(string screenName)
{

}

public int Bar()
{
return 1;
}
}

public class UnderTest
{
private IFoo foo;

public int UseFoo()
{
using (IKernel kernel = new StandardKernel())
{
kernel.Bind<IFoo>().To<Foo>();
foo = kernel.Get<IFoo>(new ConstructorArgument
("screenName", Screen.DispatchScope));
}

return foo.Bar();
}
}

[TestFixture]
public class Tests
{
[Test]
public void Test()
{
Foo fake = Isolate.Fake.Instance<Foo>();
Isolate.WhenCalled(() => fake.Bar()).WillReturn(5);
Isolate.Swap.NextInstance<Foo>().With(fake);

UnderTest ut = new UnderTest();
var result = ut.UseFoo();
Assert.AreEqual(5, result);
}
}

We have class(Foo) constructor having some parameters. When we are replacing Foo class NextInstance with it fake object getting such error, while testing "System.ArgumentNullException : Cannot be null
Parameter name: root" . Please let us know, why we are getting this. Thanks
answered by sony (7.2k points)
0 votes
Hi Ohad,

Thanks, we have done it as per your previous example.
answered by sony (7.2k points)
...