Я борюсь с EasyMock. Я написал два небольших класса чтобы проиллюстрировать мою проблему:
public abstract class A {
private AtomicReference id = new AtomicReference(null);
public final int getId() {
return id.get();
}
public final boolean setId(int id) {
return this.id.compareAndSet(null, id);
}
}
public class B extends A {
}
Затем я перехожу к написанию тестового метода следующим образом:
public class EasyMockTester extends EasyMockSupport {
@Test
public void test() {
B b = EasyMock.createStrictMock(B.class);
EasyMock.expect(b.getId()).andReturn(100);
replayAll();
int id = b.getId();
System.out.println("The ID is: " + id);
verifyAll();
}
}
Проблема в том, что я хочу, чтобы EasyMock просто имитировал экземпляр класса B (мой фактический класс не пуст, а вместо этого добавляет больше методы к методам, унаследованным от абстрактного класса). Вместо этого EasyMock каким-то образом фактически входит в код класса A и начинает жаловаться на исключение NullPointerException. Как заставить EasyMock имитировать класс, расширяющий абстрактный класс?
Когда я запускаю этот тест, я получаю следующую трассировку отказа:
java.lang.NullPointerException at com.my.project.package.tests.A.getId (A.java:9) в com.my.project.package.tests.EasyMockTester.test (EasyMockTester.java:11) в sun.reflect.NativeMethodAccessorImpl.invoke0 (Собственный Метод) в sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:39) в sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:25) в java.lang.reflect.Method.invoke (Method.java:597) в org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall (FrameworkMethod.java:44) в org.junit.internal.runners.model.ReflectiveCallable.run (ReflectiveCallable.java:15) в org.junit.runners.model.FrameworkMethod.invokeExplosively (FrameworkMethod.java:41) в org.junit.internal.runners.statements.InvokeMethod.evaluate (InvokeMethod.java:20) в org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored (BlockJUnit4ClassRunner.java:79) в org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:71) в org.junit.runners.BlockJUnit4ClassRunner.runChild (BlockJUnit4ClassRunner.java:49) в org.junit.runners.ParentRunner $ 3.run (ParentRunner.java:193) в org.junit.runners.ParentRunner $ 1.schedule (ParentRunner.java:52) в org.junit.runners.ParentRunner.runChildren (ParentRunner.java:191) в org.junit.runners.ParentRunner.access $ 000 (ParentRunner.java:42) в org.junit.runners.ParentRunner $ 2.evaluate (ParentRunner.java:184) в org.junit.runners.ParentRunner.run (ParentRunner.java:236) в org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run (JUnit4TestReference.java:49) в org.eclipse.jdt.internal.junit.runner.TestExecution.run (TestExecution.java:38) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:467) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests (RemoteTestRunner.java:683) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run (RemoteTestRunner.java:390) в org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main (RemoteTestRunner.java:197)
О да, я использую Eclipse 3.6.2, JUnit 4.8.2 и EasyMock 3.0.
РЕДАКТИРОВАТЬ: Кажется, PowerMock может обрабатывать имитирующие методы final, унаследованные от абстрактных классов! http://code.google.com/p/powermock/wiki/MockFinal