Bienvenue sur mon blog !

Powermock et playframework 2.3

Sur un projet en cours de développement, après la montée de version de play framework 2.2.4 vers la version 2.3.3, j’ai eu quelques soucis avec mes tests powermock, en voici le détail et les solutions apportées.

VerifyError : Java > 1.7.0_60

L’erreur :

        [error] Test unit.models.UserTest.update failed: java.lang.VerifyError: Bad  method call from inside of a branch
        [error] Exception Details:
        [error]   Location:
        [error]     models/ModelBasic.(Lorg/powermock/core/IndicateReloadClass;)V @42: invokespecial
        [error]   Reason:
        [error]     Error exists in the bytecode
        [error]   Bytecode:
        [error]     0000000: 2a2b 4e4d 1300 12b8 0018 04bd 000f 5903
        [error]     0000010: 2d53 1301 6db8 001d b800 233a 0519 05b2
        [error]     0000020: 0027 a500 0e2a 01c0 0029 b700 2ca7 000a
        [error]     0000030: 2c2d b700 2c01 57b1
        [error]   Stackmap Table:
        [error]     full_frame(@48,{UninitializedThis,Object[#41],UninitializedThis,Object[#41],Top,Object[#15]},{})
        [error]     full_frame(@55,{Object[#2],Object[#41],Object[#2],Object[#41],Top,Object[#15]},{})
        [error] , took 0.086 sec
        [error]     at java.lang.Class.forName0(Native Method)
        [error]     at java.lang.Class.forName(Class.java:190)
        [error]     at javassist.runtime.Desc.getClassObject(Desc.java:43)
        [error]     at javassist.runtime.Desc.getClassType(Desc.java:152)
        [error]     at javassist.runtime.Desc.getType(Desc.java:122)
        [error]     at javassist.runtime.Desc.getType(Desc.java:78)
        [error]     at unit.models.UserTest.update(UserTest.java:29)
        [error]     ...

Explication : Le problème fait l’objet d’un ticket sur le bugtracker de powermock et de java.

Solution : En attendant le correctif, il faut modifier le fichier Build.scala afin de passer un paramètre supplémentaire au lancement de java, uniquement lors des tests.

Soit pour Java 7 :

javaOptions in (Test) += "-XX:-UseSplitVerifier"

Soit pour Java 7 et Java 8 :

javaOptions in (Test) += "-noverify"

Non remontée des tests en erreur au niveau global

Explication : Nous voyons dans les logs ci-dessous que le test testMockExample de la classe UserUnitTest failed, néanmoins les tests sont en succès.

[error] Test unit.UserUnitTest.testMockExample failed: expected:<'firstName[2]'> but was:<'firstName[]'>, took 0.884 sec
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[success] Total time: 4 s, completed 29 sept. 2014 20:55:06

Le code de la classe de tests

@RunWith(PowerMockRunner.class)
@PrepareForTest({Ebean.class, User.class, Model.Finder.class})
public class UserUnitTest {


    @Test
    public void testMockExample() {
        ...
    }

}

Solution : l’utilisation d’un runner junit, à savoir le runner PowerMockRunner est le responsable de ce problème. L’utilisation d’une « Rule » en remplacement résout le problème.

@PrepareForTest({Ebean.class, User.class, Model.Finder.class})
public class UserUnitTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @Test
    public void testMockExample() {
        ...
    }

}

Les logs de tests après correction :

[error] Test unit.UserUnitTest.testMockExample failed: expected:<'firstName[2]'> but was:<'firstName[]'>, took 2.086 sec
[error] Failed: Total 1, Failed 1, Errors 0, Passed 0
[error] Failed tests:
[error] 	unit.UserUnitTest
[error] (test:testOnly) sbt.TestsFailedException: Tests unsuccessful
[error] Total time: 4 s, completed 29 sept. 2014 20:59:48

Il ne faut pas oublier d’importer les librairies suivantes :

  • powermock-module-junit4-rule
  • powermock-classloading-xstream

Add a Comment

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *