2010-07-02 10 views

Respuesta

11

EasyMock es un marco de pruebas para "para las interfaces (y objetos a través de la extensión de clase)" por lo que puede burlarse de una clase sin una interfaz. Considere crear un objeto interconectado con un accesorio para su clase estática y luego simular ese acessor.

EDITAR: Por cierto, no recomendaría hacer clases estáticas. Es mejor tener todo interconectado si estás haciendo TDD.

3

En general, no es posible simular un método estático sin utilizar algún tipo de descriptor de acceso, lo que parece frustrar el propósito de utilizar un método estático. Puede ser bastante frustrante.

Hay una herramienta que conozco llamada "TypeMock Isolator" que utiliza algún tipo de magia satánica para burlarse de los métodos estáticos, pero esa herramienta es bastante costosa.

El problema es que no conozco ninguna forma de anular un método estático. No puedes declararlo virtual. no puedes incluirlo en una interfaz.

Siento ser un nelly negativo.

9

si acaso PowerMock no está disponible por cualquier razón:

podría mover la llamada estática a un método, reemplazar este método en la creación de instancias de la clase a prueba en la clase de prueba, crear una interfaz local en la prueba clase y utilizar su método en el método alterada temporalmente:

private interface IMocker 
{ 
    boolean doSomething(); 
} 

IMocker imocker = EasyMock.createMock(IMocker.class); 

... 

@Override 
void doSomething() 
{ 
    imocker.doSomething(); 
} 

... 

EasyMock.expect(imocker.doSomething()).andReturn(true); 
0

Adición de un exemple sobre cómo implementa mock estática a lo largo de mock regular de clases inyectados con EasyMock/PowerMock, ya que el exemple vinculada sólo muestra mock estática.

Y con PowerMockRunner los servicios de no están conectados en el servicio @TestSubject para probar.

Let decir que tenemos un servicio que queremos probar, ServiceONE:

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 

@Service 
public class ServiceOne { 

    @Autowired 
    private ServiceTwo serviceTwo; 

    public String methodToTest() { 
     String returnServ2 = serviceTwo.methodToMock(); 
     return ServiceUtils.addPlus(returnServ2); 
    } 
} 

que llama a otro servicio que vamos a querer burlarse, ServiceTwo:

import org.springframework.stereotype.Service; 

@Service 
public class ServiceTwo { 

    public String methodToMock() { 
     return "ServiceTwoReturn"; 
    } 
} 

Y el que llama a una clase final método estático, ServiceUtils:

public final class ServiceUtils { 

    public static String addPlus(String pParam) { 
     return "+" + pParam; 
    } 
} 

Al llamar ServiceOne.methodToTest() obtenemos "+ServiceTwoReturn" como devolución.


Prueba Junit con EasyMock, burlando sólo el ServiceTwo servicio resorte inyectada:

import static org.easymock.EasyMock.expect; 
import static org.easymock.EasyMock.replay; 
import static org.easymock.EasyMock.verify; 
import static org.junit.Assert.assertEquals; 

import org.easymock.EasyMockRunner; 
import org.easymock.Mock; 
import org.easymock.TestSubject; 
import org.junit.Test; 
import org.junit.runner.RunWith; 

@RunWith(EasyMockRunner.class) 
public class ExempleTest { 

    @TestSubject 
    private ServiceOne serviceToTest = new ServiceOne(); 

    @Mock 
    private ServiceTwo serviceMocked; 

    @Test 
    public void testMethodToTest() { 
     String mockedReturn = "return2"; 

     expect(serviceMocked.methodToMock()).andReturn(mockedReturn); 
     replay(serviceMocked); 

     String result = serviceToTest.methodToTest(); 

     verify(serviceMocked); 

     assertEquals("+" + mockedReturn, result); 
    } 
} 

Prueba Junit con EasyMock & PowerMock, el imitar el servicio de Primavera ServiceTwo inyectado sino también la final clase y su método estático:

import static org.easymock.EasyMock.expect; 
import static org.junit.Assert.assertEquals; 
import static org.powermock.api.easymock.PowerMock.createMock; 
import static org.powermock.api.easymock.PowerMock.mockStatic; 
import static org.powermock.reflect.Whitebox.setInternalState; 

import org.easymock.Mock; 
import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.powermock.api.easymock.PowerMock; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest(ServiceUtils.class) 
public class ExempleTest { 

    private ServiceOne serviceToTest; 

    private ServiceTwo serviceMocked; 

    @Before 
    public void setUp() { 
     serviceToTest = new ServiceOne(); 
     serviceMocked = createMock(ServiceTwo.class); 
     // This will wire the serviced mocked into the service to test 
     setInternalState(serviceToTest, serviceMocked); 
     mockStatic(ServiceUtils.class); 
    } 

    @Test 
    public void testMethodToTest() { 
     String mockedReturn = "return2"; 
     String mockedStaticReturn = "returnStatic"; 

     expect(serviceMocked.methodToMock()).andReturn(mockedReturn); 
     expect(ServiceUtils.addPlus(mockedReturn)).andReturn(mockedStaticReturn); 
     PowerMock.replayAll(); 

     String result = serviceToTest.methodToTest(); 

     PowerMock.verifyAll(); 

     assertEquals(mockedStaticReturn, result); 
    } 
} 
Cuestiones relacionadas