0

I am trying to figure out a way to mock the method inside the following builder for my unit test.

public class A  {
  private C ObjectC;
  private D ObjectD; 

  public getObjectC() {
    // This should not be executed in Unit test as object creation involves external systems.
    // The object C creation depends upon the properties set by Withers inside the inner Builder class.
    return new C();
  }

  public A(ABuilder builder) {
    this.ObjectD = builder.ObjectD;
    this.ObjectC = geObjectC();
  }

  // Similarly there are three for* methods.
  public D forXYZ(final String xyz) {
    this.ObjectD.setXYZ(xyz);
    // Sometimes based on the property of XYX, the value of ABC changes.
    this.ObjectD.setABC(null);
    return this.ObjectD;
  }

  public static class ABuilder() {
    private D ObjectD;

    // Similar to the below wither method, I have four Withers with few branch logic to built Object D
    public A withFoo(final String foo) {
      this.ObjectD.setFoo(foo);
      return this;
    }

    public A build() { 
      return new A(this);
    }
  }

My Unit test class

A ObjectA = new A.ABuilder().withFoo("foo").build();
assertEquals(A.getObjectD().getFoo(),"foo");
// Similarly assert other properties of Object D. This assertion is required as the property values varies based on what the user passes in the wither.
// Eg : If 'even' is set for value 10, 'odd' is set for value 5.

D ObjectD = A.forXYZ("Request");
ObjectD.doSomething();

// Now assert the properties of D and see if proper XYZ is set.
// Similarly I have two three for* methods inside A used for modifying the property of D after creation.

// The inside builder takes care of the creation of ObjectD with properties that are going to be set only once and changes very rarely. Where as the outside class A has for* methods which handles the setters of other properties which are going to be set multiple times.

D ObjectD = A.forXYZ("Request");
ObjectD.doSomethingXYZ();
A.forABC("RequestId").doSomethingABC();

Tried using Spy but it did not mocked the internal getObjectC method.

@Mock C ObjectC;
A a = spy(new A());
doReturn(ObjectC).when(A).getObjectC();

Currently using TestNG and Mockito for my Unit tests. I don't want to use PowerMockito to achieve this. How can I mock the above use case ?

  • 1
    I don't understand what you're trying to achieve. Your ABuilder is a static class, you don't need am instance of A for it. – daniu Nov 16 '19 at 17:48
  • I am returning the instance of A to the user class which is consuming the library. And I have few other instance variables and methods inside the class which I have not explicitly mentioned. – Nantha kumar Nov 16 '19 at 17:53
  • You won't be able to mock things that happen within the constructor. Consider passing C as a parameter instead. – second Nov 16 '19 at 19:09
  • @second I can pass C as a parameter to the constructor of A. This will result in logic of Inner Builder class not getting covered completely. And we want the consumers of A to construct A only with the help of Builder class. I wanted to replicate the exact consumer behaviour while building the class. – Nantha kumar Nov 16 '19 at 19:25
  • 1
    So what is it you're testing exactly? Please post a full minimal test case. – daniu Nov 16 '19 at 19:30
  • @daniu Edited the question with minimal test case. – Nantha kumar Nov 17 '19 at 04:25
  • @Nanthakumar: The example doesnt explain why your `Builder` would not be covered if you move the creation of `C` to there. If an external system is required to build `C` you need to have a separate integration test for this anyway. – second Nov 17 '19 at 17:18
  • Yeah, move the creation of `C` to an additional class you can then mock in `A`. – daniu Nov 17 '19 at 18:15

0 Answers0