oneself
oneself

Reputation: 40301

Patching Java classes with a mock implementation in a unit test

I have a class A which instantiates an object from class B internally. That second class has lots of external side-effects, e.g. it uses a network connection.

public class A {
  private B b;
  public A() {
    b = new B(); // 3rd party class that calls out externally (e.g. to a db)
  }
}

I would like to unit test class A by providing a mock implementation of class B. I can easily create a mocked version of B by writing my own class or using something like Mockito and other frameworks, but how do I inject this mock implementation into class A's code?

I guess I could ask for an instance of class B in class A's constructor, but that seems ugly. No one really needs to know how class A does it's business.

Python has a "mock" library that allows you to "patch" functions at run time during a test. Does Java have something similar?

Upvotes: 3

Views: 4008

Answers (3)

Rogério
Rogério

Reputation: 16390

This is trivial to solve with the JMockit mocking API:

public class ATest
{
    @Test
    public void myTest(@Mocked B mockB)
    {
        // Record expectations on "mockB", if needed.

        new A().doSomethingUsingB();

        // Verify expectations on "mockB", if applicable.
    }
}

Upvotes: 0

Martin
Martin

Reputation: 7149

In this scenario I typically have a 2nd package (default) scope constuctor that allows you to pass a mock in for testing purposes.

public class A {
  private B b;

  /*
  *  Used by clients
  */
  public A() {
    this(new B());
  }

  /*
  * Used by unit test
  * 
  * @param b A mock implementation of B
  */
  A(B b) {
    this.b = b;
  }
}

Upvotes: 3

Chris Thompson
Chris Thompson

Reputation: 35598

Check out Mockito. Ultimately, based on your design, you'll need to use reflection to get the mock instance of B into A.

Upvotes: 0

Related Questions