Powermock: Can not run TestSuite when SWT Classes are involved

Created on 25 Jul 2015  路  6Comments  路  Source: powermock/powermock

_From [email protected] on August 07, 2014 09:36:42_

I have some test for features in an Eclipse RCP project.
No SWT Components are involved directly, but some files needed for the test import SWT components. (e.g. org.eclipse.swt.graphics.Image).

When the test are run stand-alone, everything is fine.
But as soon as they are put into a TestSuite, all tests fail with the following error:

java.lang.UnsatisfiedLinkError: Could not load SWT library. Reasons:
no swt-win32-3836 in java.library.path
no swt-win32 in java.library.path
Native Library C:\Users\franzm.swt\lib\win32\x86_64\swt-win32-3836.dll already loaded in another classloader
Can't load library: C:\Users\franzm.swt\lib\win32\x86_64\swt-win32.dll

at org.eclipse.swt.internal.Library.loadLibrary(Library.java:331)
at org.eclipse.swt.internal.Library.loadLibrary(Library.java:240)
at org.eclipse.swt.internal.C.<clinit>(C.java:21)
at org.eclipse.swt.widgets.Widget.<clinit>(Widget.java:103)
at com.example.app.client.ui.filters.FilterDtoUtil.formatDateFormat(FilterDtoUtil.java:325)
at com.example.app.client.ui.filters.FilterDtoUtil.getMarketVariantsProductionSitesWithDates(FilterDtoUtil.java:358)
at com.example.app.client.ui.filters.factories.FilterContributor.getFilterRow(FilterContributor.java:566)
at com.example.app.client.ui.filters.factories.AbstractBigFilterFactory.getFilterRow(AbstractBigFilterFactory.java:59)
at com.example.app.client.ui.excelexport.AbstractExcelTest.before(AbstractExcelTest.java:73)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:132)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:104)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.junit.runners.Suite.runChild(Suite.java:127)
at org.junit.runners.Suite.runChild(Suite.java:26)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
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)

From my point of view, PowerMockito tries to load the DLL for every tests and blocks itself there.

_Original issue: http://code.google.com/p/powermock/issues/detail?id=511_

Medium bug imported

All 6 comments

_From [email protected] on August 28, 2014 04:30:42_

You need to suppress the static initializer that loads the DLL.

Status: Invalid

_From [email protected] on September 01, 2014 23:07:20_

Can you give me a hint how?

_From [email protected] on September 12, 2014 10:42:28_

Did you come up with a solution for this?

Hello everyone, excuse me to get in discussion like that, but I am currently facing this issue and i wonder if somebody Has found a way to solved this? even a workaround will be helpful.

With thanks.

The suppress static initializer hint saved my day.
Here is an example how I solved it with PowerMockito:

@RunWith(PowerMockRunner.class)
@SuppressStaticInitializationFor({
        "org.eclipse.swt.widgets.Display"
})
@PrepareForTest({
        Display.class
})
public abstract class MockDisplayTest {

    @Before
    public void before() throws Exception {
        PowerMockito.suppress(org.eclipse.swt.widgets.Display.class.getConstructors());
        PowerMockito.mockStatic(org.eclipse.swt.widgets.Display.class);
        Display display = Mockito.mock(Display.class);
        PowerMockito.doAnswer(invocation -> {
            Runnable runnable = invocation.getArgumentAt(0, Runnable.class);
            runnable.run();
            return null;
        }).when(display).asyncExec(Mockito.any());
        PowerMockito.doAnswer(invocation -> {
            Runnable runnable = invocation.getArgumentAt(0, Runnable.class);
            runnable.run();
            return null;
        }).when(display).syncExec(Mockito.any());
        PowerMockito.when(org.eclipse.swt.widgets.Display.getDefault()).thenReturn(display);
        PowerMockito.when(org.eclipse.swt.widgets.Display.getCurrent()).thenReturn(display);
    }
}

I am sorry to revive this old thread again, but @hgschwibbe code above no longer works. When trying this I get:
org.mockito.exceptions.misusing.NotAMockException: Argument should be a mock, but is: class java.lang.Class

PowerMockito.mockStatic does not mock the class properly. Is this a bug or did swt lib change something? What has happened?

Was this page helpful?
0 / 5 - 0 ratings