simulacro o talón para llamada encadenada

protected int parseExpire(CacheContext ctx) throws AttributeDefineException { Method targetMethod = ctx.getTargetMethod(); CacheEnable cacheEnable = targetMethod.getAnnotation(CacheEnable.class); ExpireExpr cacheExpire = targetMethod.getAnnotation(ExpireExpr.class); // check for duplicate setting if (cacheEnable.expire() != CacheAttribute.DO_NOT_EXPIRE && cacheExpire != null) { throw new AttributeDefineException("expire are defined both in @CacheEnable and @ExpireExpr"); } // expire time defined in @CacheEnable or @ExpireExpr return cacheEnable.expire() != CacheAttribute.DO_NOT_EXPIRE ? cacheEnable.expire() : parseExpireExpr(cacheExpire, ctx.getArgument()); } 

ese es el método para probar,

 Method targetMethod = ctx.getTargetMethod(); CacheEnable cacheEnable = targetMethod.getAnnotation(CacheEnable.class); 

Tengo que burlarme de tres CacheContext, Method y CacheEnable. ¿Hay alguna idea para hacer que el caso de prueba sea mucho más simple?

Mockito puede manejar los talones encadenados :

 Foo mock = mock(Foo.class, RETURNS_DEEP_STUBS); // note that we're stubbing a chain of methods here: getBar().getName() when(mock.getBar().getName()).thenReturn("deep"); // note that we're chaining method calls: getBar().getName() assertEquals("deep", mock.getBar().getName()); 

AFAIK, el primer método en la cadena devuelve un simulacro, que está configurado para devolver su valor en la segunda llamada al método encadenado.

Los autores de Mockito señalan que esto solo debería usarse para el código heredado . Una mejor cosa que hacer de otra manera es insertar el comportamiento en CacheContext y proporcionar la información que necesita para realizar el trabajo. La cantidad de información que extrae de CacheContext sugiere que su clase tiene envidia característica .

Encontré JMockit más fácil de usar y lo cambié por completo. Ver casos de prueba usándolo:

https://github.com/ko5tik/andject/blob/master/src/test/java/de/pribluda/android/andject/ViewInjectionTest.java

Aquí me burlo de la clase de base de actividad, que proviene de Android SKD y que está completamente cortada. Con JMockit puedes burlar las cosas que son finales, privadas, abstractas o cualquier otra cosa.

En su caso de prueba, se vería así:

 public void testFoo(@Mocked final Method targetMethod, @Mocked final CacheContext context, @Mocked final CacheExpire ce) { new Expectations() { { // specify expected sequence of infocations here context.getTargetMethod(); returns(method); } }; // call your method assertSomething(objectUndertest.cacheExpire(context)) 

Mi sugerencia para simplificar su caso de prueba es refactorizar su método.

Cada vez que me encuentro con problemas para probar un método, es un olor a código para mí y me pregunto por qué es difícil probarlo. Y si el código es difícil de probar, probablemente sea difícil de usar y mantener.

En este caso, es porque tienes una cadena de métodos que tiene varios niveles de profundidad. Quizás pase en ctx, cacheEnable y cacheExpire como parámetros.