0

I have a class as below

public Class CLZA {

     private Object obj1;
     private Object obj2;
     private StringBuilder strBuilder;

     public CLZA (CLZB objB) {
          obj1 = objB.fetchValueOfObj(Request.type1);
          obj2 = objB.fetchValueOfObj(Request.type2);
          strBuilder = new StringBuilder();
     } 

     public double computeValue(...) {
          if (this.obj1 == 1.0) {
              ...
          }
          if (this.obj2 == 2.0) {
              ...
          }
          strBuilder.append("This is the line I got NPE now");
     }
}

Right now, I am trying to do something like this.

@RunWith(PowerMockRunner.class)
@PrepareForTest({CLZA.class, StringBuilder.class})
public class ClzATest {

    private CLZA objA;

    @Mock
    private CLZB objB;

    @Before
    public void setUp() throws Exception {
        objA = new CLZA(objB);
        when(objB.fetchValueOfObj(any(Request.class))).thenAnswer(
                invocation -> {
                    Object argument = invocation.getArguments()[0];
                    if (argument.equals(Request.type1)) {
                        return 1.0;
                    } else if (argument.equals(Request.type2)) {
                        return 2.0;
                    } else {
                        return 0.0;
                    }
                });

    }

    @Test
    public void testComputeValue() {
        double value = objA.computeValue(...);
        assertEquals(2.0, value);
    }
}

I have following questions/issues:

  1. As you can see, I want to mock the value of the objB returned. Can I pass the mocked objB to the constructor when I instantiate the Class CLZA? should I mock CLZA also? If I need to mock CLZA, how can I related it to my mocked objB?

  2. Right now, I keep getting NullPointerException at the line strBuilder.append("This is the line I got NPE now");. It seems strBuilder is not instantiated. Can anyone help on how to test in this scenario?

Appreciate it.

Laodao
  • 1,547
  • 3
  • 17
  • 39
  • Move the line with `objA = ` to _after_ the line with `when`. – Dawood ibn Kareem Mar 04 '20 at 01:04
  • @DawoodsaysreinstateMonica, I moved `objA = new CLZA(objB);` after `when(objB.fetchValueOfObj(any(Request.class))).thenAnswer(...`, it still throw NPE. – Laodao Mar 04 '20 at 02:17
  • There is nothing in your posted test that requires `@PrepareForTest({CLZA.class, StringBuilder.class})` I would guess that is messing with the `CLZA` constructor. See [what does preparefortest really mean?](https://stackoverflow.com/questions/56430071/what-does-preparefortest-in-powermock-really-mean) – DCTID Mar 04 '20 at 02:44
  • @DCTID, I removed the `PrepareForTest...`, it still throw NPE. :( – Laodao Mar 04 '20 at 03:34

1 Answers1

0

It turns out the NPE was caused by another issue. This unit testing is working fine. Sorry for the misleading.

Laodao
  • 1,547
  • 3
  • 17
  • 39