2016-08-31 5 views
2

У меня есть несколько классов тестов, которые должны проверять, что функции GLFW были вызваны. Но когда я хочу, чтобы выполнить все тесты в IntelliJ я получаю ошибку:JUnit & Powermock: родная библиотека уже загружена в другой загрузчик классов

Native Library lwjgl.dll already loaded in another classloader 

я использую Powermock, чтобы убедиться, что статические методы были названы:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({GLFW.class}) 
public class GlfwWindowImplTest { 
    // ... 
    @Test 
    public void update_swapsBufferAndPollsEvents() { 
     GlfwWindowImpl target = new GlfwWindowImpl(1L); 
     mockStatic(GLFW.class); 

     target.update(); 

     verifyStatic(); 
     GLFW.glfwSwapBuffers(1L); 
     verifyStatic(); 
     GLFW.glfwPollEvents(); 
    } 
} 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({GLFW.class}) 
public class GlfwWindowSystemImplTest { 
    // ... 
    @Test(expected = GlfwInitializeException.class) 
    public void initialize_throwsExceptionIfGlfwInitFails() { 
     GlfwWindowSystemImpl target = new GlfwWindowSystemImpl(); 
     mockStatic(GLFW.class); 
     when(GLFW.glfwInit()).thenReturn(GL_FALSE); 

     target.initialize(); 
    } 
} 
+0

'@PrepareForTest ({GLFW.class})' ammend класс и загрузить его в новый загрузчик классов. – talex

+0

@Exhauzt Вы когда-нибудь получали решение этой проблемы? Я не могу понять, что говорит вам следующее решение. У вашего исходного кода уже есть '@PrepareForTest ({GLFW.class})' ... так что вы должны делать по-другому? Спасибо – Nova

+0

Нет, я на самом деле не нашел решения, но вскоре должен был сделать еще один проект ... Поэтому я не слишком много копал в этой теме, чтобы найти решение. И я тоже не понимаю этого решения. – danielspaniol

ответ

0

@PrepareForTest({GLFW.class}) создать новую ammended ClassLoader и нагрузки класс в нем. Я подозреваю, что GLFW загружается lwjgl библиотека в разделе статического инициализатора.

Вы можете попытаться выгрузить библиотеку, но я не знаю, к каким последствиям это может привести.

Предлагаю обернуть GLFW и использовать эту обертку в вашем приложении.

+0

Это очень запутанный ответ. Вы считаете, что решение является '@PrepareForTest ({GLFW.class})'? Это то, что уже имеет его оригинальный код. Как выглядит «обтекание GLFW и использование этой оболочки в вашем приложении», как вы сказали? Просьба уточнить :) – Nova

+0

'@PrepareForTest ({GLFW.class})' это не решение, а причина проблемы. Это приводит к перезагрузке класса. Перегрузка класса приводит к выполнению статического раздела и выполнению статического раздела приводит к второй загрузке библиотеки 'lwjgl.dll'. – talex

1

Возможно, немного поздно ответить на это сообщение, но у меня возникла аналогичная проблема, и я смог решить ее с помощью PowerMock. PowerMock имеет @SuppressStaticInitializationFor, который поможет вам преодолеть эту проблему. Раздел Подавить статический инициализатор в ссылке ниже есть хороший пример о том, как сделать это:

https://github.com/powermock/powermock/wiki/Suppress-Unwanted-Behavior

В основном, в вашем случае может быть класс, который звонит System.loadLibrary ("LWJGL "). Вам нужно найти этот класс. Пример:

public class SomeClass { 
    ... 
    static { 
     System.loadLibrary ("lwjgl"); 
    } 
    ... 
} 

Затем в использовании класса теста @SuppressStaticInitializationFor с полным именем класса:

@SuppressStaticInitializationFor("com.example.SomeClass") 

Если в случае класс делает вызов LoadLibrary является внутренним классом, то вам нужно добавить $ InnerClass, чтобы полностью квалифицировать внутренний класс. Пример:

public class SomeClass { 
    ... 
    public static class SomeInnerClass { 
     static { 
      System.loadLibrary ("lwjgl"); 
     } 
    } 
    ... 
} 

Тогда вам нужно использовать:

@SuppressStaticInitializationFor("com.example.SomeClass$SomeInnerClass") 
+0

Никогда не поздно! –