Mocking en Java

Première stratégie

1ère stratégie : Java.lang.reflect.Proxy

Classe spéciale qui permet d’intercepter des méthodes identifiées par une interface à Runtime. Cela permet de créer dynamiquement des implémentations d’interfaces qu’on peut contrôler.

L’interception des méthodes se fait via la méthode (classe InvocationHandler): public Object invoke(Object proxy, Method method, Object[] args)

Voici un exemple permettant de comprendre le concept général.

	
package fr.umlv.mocking.proxy;

public class Sum implements ISum {
    public Integer value1;
    public Integer value2;
 
    public Sum(Integer val1, Integer val2) {
        value1 = val1;
        value2 = val2;
    }
 
    public Integer sum() {
        return new Integer(value1.intValue() + value2.intValue());
    }
	
	public interface ISum {
		Integer sum();
	}
}
	

La classe Sum permet de réaliser la somme de deux entier.

	
package fr.umlv.mocking.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
public class Handler implements InvocationHandler {
 
    public Sum trueSum;
 
    public Handler(Sum sum) {
        this.trueSum = sum;
    }
 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    	System.out.println("j'ai intercepter l'appel de la methode");
    	return new Integer(0);
    }
}
	

Nous créons ensuite un handler qui va gérer l'appel de la méthode. Cette classe implémente l'interface InvocationHandler et implante la méthode invoke qui possède quelques paramètres spéciaux. Pour simplifier, cette méthode sera appelée à la place de la méthode "sum" de la classe "Sum". Nous afficherons un message d'alerte et la méthode renverra dans tous les cas la valeur zéro.

	
import java.lang.reflect.Proxy;

public class Test {

    public static void main(String[] args)  {
        
        Sum sum = new Sum(new Integer(2), new Integer(3));
        Handler handler = new Handler(sum);
        Class[] interfacesArray = new Class[] {ISum.class};

        // Creation du proxy
        ISum proxySum = (ISum) Proxy.newProxyInstance(Sum.class.getClassLoader(), interfacesArray, handler);
        
        System.out.println(proxySum.sum());
     }
}
	

Voici maintenant le code de test qui va instancier les objets Sum, le Handler et le proxy. A l'affichage, nous obtenons 0 et non pas 5 comme attendu.

Inconvénients liés à Java.lang.reflect.Proxy