Atul
Atul

Reputation: 93

How to mock a method called inside another method?

I would like to explain my problem using an example.

class A
{
    Fun1()
    {
        // some code
        B obj2 = new B();
        obj2.Fun2();
    }
}

class B
{
    Fun2() 
    {
        // some code
    }
}

// Test class for Class A
class A_Test
{
    public Fun1_Test()
    {
        A obj1 = new A();
        A.Fun1();
    }
}

Here I am calling Fun1 which calls Fun2(). I want to mock call to Fun2().

I need to do the initialization of Class B object in Fun1() only, I don't want to do it using the constructor.

It is possible to mock call to Fun2()?

Upvotes: 9

Views: 13935

Answers (2)

dcastro
dcastro

Reputation: 68750

You can't, because Fun2 is an instance method of an object created inside Fun1.

Since A depends on B, B should be injected into A, if you want to achieve true isolation.

You should also "Depend upon abstractions", as advertised by the Dependency Inversion Principle. Make B implement an interface IB, and make A depend on IB instead. Then, you mock the interface IB and inject that mock instead.

class A
{
    public Fun1(IB ib) { ib.Fun2(); }
}

interface IB
{
    Fun2();
}

class B : IB
{
    public Fun2() {}
}

// Test class for Class A
class A_Test
{
    public Fun1_Test()
    {
        var bMock = new Mock<IB>();
        bMock.Setup(b => b.Fun2());

        A obj1 = new A();
        A.Fun1(bMock.Object);
    }
}

Read:

  1. Dependency Inversion Principle
  2. Dependency Injection

Upvotes: 12

Amol
Amol

Reputation: 4037

Classic example which shows how if you cannot unit test a particular component, REFACTOR the component!

This is where is love what any mocking framework enforces you to do - write decoupled code.

In your example, the class A is very tightly coupled with the concrete implementation of B. You could decouple it using (like most of the answers suggest) dependency injection. By doing so, you would end up depending on the IB abstraction than any concrete implementation of it.

Upvotes: 4

Related Questions