静态模拟抛出NullPointerException异常

3

我尝试编写测试,然后使用静态类。

我有一个名为Person的类:

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

类别 ID:

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

这是我的测试:

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();
  }
}

当我运行测试时,它抛出了NPE:

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

在第17行,它调用了静态方法Id.generate的代码。我认为这是错误的行为。

3个回答

2

调用 new Person(null) 会抛出此异常,因为构造函数调用了 generate(name),而 generate 又调用了 name.equals。这就是你的问题所在:namenull

在你的情况下,一种解决方法是使用 Yoda条件 "I".equals(name)。虽然乍一看这看起来很奇怪,但它确实可以依赖于java.lang.String.equals中进行null检查,这意味着你不必自己进行检查。


我知道NPE抛出name.equals("I"),这是有意的。这证明了EasyMock.expect(Id.generate(null)).andReturn(55);调用了Id.generate(null)。在我看来,这是错误的行为。 - Radoslav

0

我找到了解决方案。 测试类必须扩展PowerMockTestCase。

正确的写法:

public class MockStaticTest extends PowerMockTestCase {
...
}

0

你正在将null作为参数传递,那么为什么它不应该生成 NullPointerException?在第17行你应该提供一个正确的参数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接