ClassLoader генерирует исключение NullPointerException при попытке частичного макета класса с помощью JMockit - PullRequest
0 голосов
/ 11 ноября 2011

Использование Eclipse 3.6.1
Java 1.6.0_26
JMockit 0.999.10

ОБНОВЛЕНИЕ: мне удалось создать SSCCE, который я выкладываю ниже:

ОБНОВЛЕНИЕ2: добавлен DaemonHelper. Кроме того, если я удаляю DaemonHelper из конструктора, я получаю вместо него ClassCircularityError. Относящиеся

Я пытаюсь выполнить частичную имитацию класса, одновременно высмеивая несколько зависимостей класса, когда получаю NPE из загрузчика классов. Стек вызовов NPE показан ниже

У меня есть Daemon Класс, такой как:

public class Daemon extends DaemonParent {

public Daemon(ConfigParent config, DaemonHelper helper) {
    super(config, helper);
}

@Override
public void execute() {
    log("Starting");
    if (config.test()) {
        log("Testing");
    }

    log("Ending");  
}
}

У Демона есть Родитель, подобный так:

public abstract class DaemonParent extends Thread {

protected ConfigParent config;
protected DaemonHelper helper;

public DaemonParent(ConfigParent config, DaemonHelper helper) {
    this.config = config;
    this.helper = helper;
}


public abstract void execute();

public void log(String s) {
    System.out.println(s);
}
}

Существует вспомогательный класс, подобный:

public class DaemonHelper extends Thread {

}

Конфиг выглядит так:

public class ConfigParent {

protected ConfigHelper helper;

public ConfigParent(ConfigHelper helper) {
    this.helper = helper;
}

public boolean test() {
    return false;
}
}

Родитель конфигурации выглядит так:

public class ConfigParent implements Serializable {

protected ConfigHelper helper;

public ConfigParent(ConfigHelper helper) {
    this.helper = helper;
}

public boolean test() {
    return false;
}
}

А тест выглядит так:

public class DaemonTest {

@Test
public void testExecute(final ConfigHelper ch, final DaemonHelper dh) {
    final Config c = new Config(ch);
    final Daemon d = new Daemon(c, dh);

    new NonStrictExpectations(d) {
        {

        }
    };

    d.execute();

    new Verifications() {{
        d.log("Starting");
        d.log("Ending");
    }};
}
}

Когда я пытаюсь запустить этот тест, я получаю следующую ошибку. Обратите внимание, что эта ошибка появляется только тогда, когда DaemonParent и Daemon Helper имеют java.lang.Thread как суперкласс:

java.lang.NullPointerException
at java.lang.Thread.interrupted(Unknown Source)
at sun.misc.Resource.getBytes(Unknown Source)
at java.net.URLClassLoader.defineClass(Unknown Source)
at java.net.URLClassLoader.access$000(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.junit.internal.runners.model.EachTestNotifier.addFailure(EachTestNotifier.java:23)
at org.junit.runners.ParentRunner.run(ParentRunner.java:242)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Я попытался закомментировать блок NonStrictExpectations и блок Verifications, и я получил ту же ошибку.

NPE выбрасывается из вызова currentThread () ... который я понятия не имею, как он мог потерпеть неудачу.

Есть идеи?

1 Ответ

1 голос
/ 17 ноября 2011

Оказывается, проблема в том, что корневым суперклассом Daemon является java.lang.Thread, что вызвало проблемы с JMockit.Решением было статическое частичное моделирование методов, необходимых для теста

public class DaemonTest {

@Test
public void testExecute(final ConfigHelper ch, final DaemonHelper dh) {

new NonStrictExpectations(d) {
    @Mocked({"log"}
    Daemon d;
    @Mocked({"()"})
    DaemonHelper dh;
    {

    }
};


final Config c = new Config(ch);
final Daemon d = new Daemon(c, dh);
d.execute();

new Verifications() {{
    d.log("Starting");
    d.log("Ending");
}};
}
}
...