Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock static throws NullPointerException

I try to write test then it use static class.

I have class Person:

public class Person {
  private int id;
  public Person(String name) {
    id = Id.generate(name);
  }
  public int getId() {
    return id;
  }
}

And class Id:

public class Id {
  public static int generate(String name) {
    if (name.equals("I")) {
      return 42;
    }
    return 100;
  }
}

This is my test:

import org.easymock.EasyMock;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;

import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.testng.Assert;
import org.testng.annotations.Test;

@RunWith(PowerMockRunner.class)
@PrepareForTest( { Id.class } )
public class MockStaticTest {

  @Test
  public void test() throws Exception {
    PowerMock.mockStatic(Id.class);
    EasyMock.expect(Id.generate(null)).andReturn(55);

    PowerMock.replayAll();
    Person person = new Person(null);
    Assert.assertEquals(person.getId(), 55);
    PowerMock.verifyAll();
  }
}

When I run test, it throws NPE:

java.lang.NullPointerException
    at Id.generate(Id.java:3)
    at MockStaticTest.test(MockStaticTest.java:17)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
...

On line 17 it calls code of static method Id.generate. In my opinion, it is wrong behavior.

like image 397
Radoslav Avatar asked Sep 08 '25 19:09

Radoslav


1 Answers

Calling new Person(null) will throw this exception as the constructor calls generate(name) and generate calls name.equals. That is your problem: name is null.

One way round this in your case would be to use the Yoda condition "I".equals(name). Although this looks odd at first glance, it does allow you to rely on java.lang.String making a null check in .equals, meaning you don't have to do it yourself.

like image 91
Bathsheba Avatar answered Sep 10 '25 09:09

Bathsheba