Mocking en Java
Deuxième stratégie
2ème stratégie : Java.lang.Instrument
On va indiquer au "class loader" de remapper la référence vers le "class file" souhaité.
J’ai une classe "Account" avec son .class correspondant. Je veux "mocker" cette classe avec la classe MockAccount. Dans le "class loader", on va remapper la référence de "Account" vers le MockAccount.class.
Si on demande une instance de "Account", je retourne une instance de "MockAccount".
// Enregistrer un agent d’instrumentation java
import java.lang.instrument.Instrumentation;
import java.lang.instrument.ClassFileTransformer;
public class MyAgent {
// Cette méthode est appelée avant la méthode main de l'application,
// Il faut que cet agent ait été spécifié à la JVM
public static void premain(String agentArgs, Instrumentation _inst) {
// On met en place le ClassFileTransformer et on l'ajoute à la VM
ClassFileTransformer trans = new MyClassFileTransformer();
_inst.addTransformer(trans);
}
}
// Ce transformer sera appelé chaque fois qu'une classe est chargée dans la JVM
import java.lang.instrument.ClassFileTransformer;
public class MyClassFileTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className,
Class<?> classBeingRedefined, ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws IllegalClassFormatException {
byte[] transformed = null;
System.out.println("Transformation de la classe " + className);
return transformed;
}
}
Packager l’agent dans un .JAR Dans le manifest, à la place du champ « Main-Class », indiquer : Premain-Class : « nom du package » + « nom de la classe Agent » Can-Redefine-Classes : true
Pour lancer l’agent Java –javaagent « chemin du JAR de l’agent »