Hace poco me preguntarón como hacerlo y no supe responder correctamente al tema, igual es algo antiguo pero la verdad es que yo no lo sabía. Por tanto hoy hablaremos de como mockear un atributo o clase estática.
Para ello nos apoyaremos en PowerMock, otro framework que nos permitirá simular nuestras clases y hacer unos test JUnit más eficientes. Este está compuesto de varias APIs para otros frameworks de simulación, como EasyMock o Mockito, y otra que nos facilitará las tareas de reflexión. En esta otra API nos centraremos para llevar a cabo el post.
Teniendo la siguiente clase con dos métodos, uno que tira de una clase estática y otro de un atributo estático, veremos como probar ambos.
Teniendo la siguiente clase con dos métodos, uno que tira de una clase estática y otro de un atributo estático, veremos como probar ambos.
public class BookController { private static BookWSClient client = new BookWSClient(); public Book getBookByStaticAttribute(final Integer id) { return client.getBook(id); } public Book getBookByStaticClass(final Integer id) { return BookWSHelper.getBook(id); } }
Para el primer caso haremos uso de la clase 'Whitebox' que es la base de la API de reflección. Con ella podremos acceder a atributos, métodos y constructores privados. Para el caso que nos corresponde, un atributo privado, usaremos el método 'setInternalState'
@RunWith(PowerMockRunner.class) public class WhiteboxExample { @Mock private BookWSClient client; private BookController controller; @Test public void getBookByStaticAttribute() throws RemoteException { Mockito.when(client.getBook(1)).thenReturn(new Book("name", "author")); Book book = controller.getBookByStaticAttribute(1); assertEquals("name", book.getName()); Mockito.verify(client, Mockito.times(1)).getBook(1); } @Before public void setUp() throws Exception { Whitebox.setInternalState(BookController.class, "client", client); controller = new BookController(); } }
En el segundo haremos uso de la anotación 'PrepareForTest' que nos permitirá mockear clases finales o clases con métodos finales, privados o estáticos. Y luego tendremos que usar el método 'mockStatic' para indicar que deseamos 'mockear' la clase estática de la que haremos uso.
@RunWith(PowerMockRunner.class) @PrepareForTest(BookWSHelper.class) // class with static method public class MockStatic { private BookController controller; @Test public void getBookByStaticClass() throws RemoteException { controller = new BookController(); PowerMockito.mockStatic(BookWSHelper.class); Mockito.when(BookWSHelper.getBook(1)).thenReturn(new Book("name", "author")); Book book = controller.getBookByStaticClass(1); assertEquals("name", book.getName()); } }
MUCHAS GRACIAS!
ResponderEliminar