2012-08-23 30 views
6

Estoy intentando simular una llamada al método final ResourceBundle.getString(). Con PowerMock 1.4.12 y EasyMock 3.1, la llamada no se burla; en su lugar, se llama el método "real".Burlando de un método final con PowerMock + EasyMock

Mi clase de prueba:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ResourceBundle.class) 
public class TestSuite { 
    @Before 
    public void setUp() throws Exception { 
     ResourceBundle resourceBundleMock = PowerMock.createNiceMock(ResourceBundle.class); 
     expect(resourceBundleMock.getString(BundleConstants.QUEUE)).andReturn("Queue"); 
     PowerMock.replay(resourceBundleMock); 

     beanBeingTested.setMessages(resourceBundleMock); 
    } 
    ... 
} 

Código de BeanBeingTested:

private ResourceBundle messages; 
... 
String label = messages.getString(BundleConstants.QUEUE); 

mensaje de error:

java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByCGLIB$$e4a02557, key Queue 
at java.util.ResourceBundle.getObject(ResourceBundle.java:384) 
at java.util.ResourceBundle.getString(ResourceBundle.java:344) 
at com.yoyodyne.BeanBeingTested.setUpMenus(BeanBeingTested.java:87) 

Cuando me paso a través del caso de prueba, el depurador muestra el tipo de beanBeingTested.messages como "EasyMock para la clase java.util.ResourceBundle", por lo que el simulador se inyecta corr ectly. (Además, no hay ningún error en la llamada al getString() dentro de la llamada expect() durante la configuración).

Con una maqueta normal en lugar de una bonita maqueta, me sale el siguiente error:

java.lang.AssertionError: 
    Unexpected method call handleGetObject("Queue"): 
    getString("Queue"): expected: 1, actual: 0 

Alguna idea de lo que estoy haciendo mal?

Gracias.

Respuesta

0

¿Por qué molestarse en burlarse de la llamada al paquete de recursos? En general, trato de evitar burlarme de los aspectos prácticos de Java, como ArrayList, Date, etc. Los paquetes de recursos (y MessageFormat.format()) caen más o menos en la misma categoría para mí. Por lo general, operan en cadenas que son fundamentales, y si estas cosas se rompen o cambian su comportamiento lo suficiente como para superar una prueba, definitivamente es algo que quiero saber :)

Solo déjalos agarrar la cuerda (que presumiblemente va a ser configurado en la interfaz de usuario, quizás después. No se moleste en afirmar el valor devuelto, ya que no desea que las ediciones del paquete rompan la prueba. Si la cadena se establece en un componente simulado de la interfaz de usuario, este es un buen lugar para cualquier objeto (String.class) que expresa correctamente el hecho de que (probablemente) no le importa la cadena específica que se muestra.

También considero un beneficio cuando la prueba falla debido a una tecla de mensaje faltante. ESO quiero saber.

3

Está creando una instancia usando EasyMock. En cambio, cuando se trabaja con métodos estáticos, debe burlarse de la clase (usando PowerMock).

Se debe trabajar de esa manera (probado con EasyMock 3.0 y 1.5 PowerMock, sin embargo):

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ResourceBundle.class) 
public class TestSuite { 
    @Before 
    public void setUp() throws Exception { 
     // mock the class for one method only 
     PowerMock.mockStaticNice(ResourceBundle.class, "getString"); 

     // define mock-behaviour on the class, when calling the static method 
     expect(ResourceBundle.getString(BundleConstants.QUEUE)).andReturn("Queue"); 

     // start the engine 
     PowerMock.replayAll(); 
    } 
} 

(Soy consciente de esta pregunta se encuentra a pocos meses de edad, pero puede ayudar a los demás, sin embargo)

+0

También estoy enfrentando el mismo problema.Pero esto todavía no está ayudando. ¿Se refiere solo a métodos finales o métodos estáticos? – Siddharth

+0

@Siddharth {{PowerMock.mockStaticNice()}} se burla de un método estático de una clase, pero deja el resto de los métodos intactos. Si este hilo no lo ayuda, debe crear una nueva pregunta, porque parece que tiene problemas diferentes. – Andy

+0

Gracias por su respuesta @Andy. Pero el tema de este hilo habla sobre el método final, pero estás hablando de método estático. ¿Me estoy perdiendo de algo? Mi problema es que hay un método de "vacío final público" que estoy tratando de burlar y la prueba llama al método real en lugar de simular. ¿Es el tema anterior diferente del que estoy hablando? Lo siento si me perdí un punto. – Siddharth

1

Trate de usar:

@PrepareForTest({ResourceBundle.class, BeanBeingTested.class}) 

Con solamente ResourceBundle en el PrepareForTest la maqueta funcionará cuando llama directamente desde el método de prueba de unidad, pero cuando se llama desde BeanBeingTested que g et el método real en uso.

Falta la documentación de Powermock en esta área.

Cuestiones relacionadas