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 »