2012-01-31 39 views
32

Actualmente estoy estudiando el framework Mockito y he creado varios casos de prueba usando Mockito. Pero luego leí que en vez de invocar maqueta (SomeClass .class) que puede utilizar el @Mock y la @InjectMocks - Lo único que tengo que hacer es anotar mi clase de prueba con @RunWith(MockitoJUnitRunner.class) o utilizar el MockitoAnnotations.initMocks(this); en el método @Before.Usando @Mock y @InjectMocks

Pero no funciona - ¡Parece que el @Mock no funcionará! Aquí están mis 2 revisiones de códigos: una que usa las anotaciones y otra que no.

¿Qué estoy haciendo mal?

public class ReportServiceImplTestMockito { 

    private TaskService  mockTaskService; // This is the Mock object 
    private ReportServiceImpl service; 

    @Before 
    public void init(){ 
     service   = new ReportServiceImpl(); 
     mockTaskService = mock(TaskServiceImpl.class); 
     service.setTaskServiceImpl(mockTaskService); 
    } 
/// ... 

Some tests 
} 

Como dije, este es un trabajo excelente. Pero el siguiente planteo:

@RunWith(MockitoJUnitRunner.class) 
public class ReportServiceImplTestMockito { 

    @Mock 
    private TaskService  mockTaskService; 

    @InjectMocks 
    private ReportServiceImpl service; 

     // Some tests 
} 

Y aquí es la clase ReportServiceImpl:

@Service 
public class ReportServiceImpl implements ReportService { 

    @Autowired 
    private TaskService taskServiceImpl; 

    public ReportServiceImpl(){} 

    public ReportServiceImpl(TaskService taskService){ 
     this.taskServiceImpl = taskService; 
    } 

    public void setTaskServiceImpl(TaskService taskServiceImpl) { 
     this.taskServiceImpl = taskServiceImpl; 
    } 
} 

¿Qué me falta?

+0

Me parece bien, a primera vista. ¿Qué es exactamente lo que está mal para ti? –

+1

@Noam ¿Seguro que está utilizando las importaciones correctas? – Brice

+0

David - Recibo una NullPointerException. Y Brice, creo que estoy usando las importaciones correctas, aquí están 'import org.jmock.auto.Mock; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; ' – Noam

Respuesta

24

O.K, tengo mi error !!! He usado el @InjectMocks pero inicialicé la misma variable en el método init() ... Entonces, lo que sucedió fue que el mockito inyectó los objetos simulados a mi variable, pero segundos después lo ejecuté, ¡inicializando esa misma variable! !!

3

no estoy seguro, pero tratan de crear una nueva instancia de ReportServiceImpl manualmente (como lo hizo en el ejemplo de trabajo):

@InjectMocks 
private ReportServiceImpl service = new ReportServiceImpl(); 
+3

Esto ya no es necesario desde Mockito 1.9 a excepción de la caja de borde. – Brice

+1

Si está utilizando 1.8, necesita crear una instancia en el inicializador o en el constructor a menos que esté usando 'MockitoAnnotations.initMocks (this)' en cuyo caso, necesita instanciarlo antes de que se invoque. – jhericks

+3

Primero, gracias por las respuestas. pero usar MockitoAnnotations.initMocks (esto) no es necesario ya que utilicé @RunWith (MockitoJUnitRunner.class). – Noam

12

Su código funciona bien para mí usando Mockito 1.9.

Usando una versión 1.8+ de Mockito me aparece un mensaje de error muy específico que me dice exactamente cómo solucionar el problema. Como lo sugiere php-coder: para Mockito 1.8+ necesitas inicializar el campo.

¿Has visto este u otro mensaje de error?

Editar:

El siguiente código funciona para mí. Pequeños cambios:

  • anotaciones Spring eliminados
  • quitan interfaz
  • Agregado Getter
  • Añadido vacío TaskService
  • ensayo añadida con System.out.println

¿Produce un error para usted? :

Servicio:

public class ReportServiceImpl { 

    private TaskService taskServiceImpl; 


    public ReportServiceImpl() { 

    } 


    public ReportServiceImpl(TaskService taskService) { 
     this.taskServiceImpl = taskService; 
    } 


    public void setTaskServiceImpl(TaskService taskServiceImpl) { 
     this.taskServiceImpl = taskServiceImpl; 
    } 


    public TaskService getTaskServiceImpl() { 
     return taskServiceImpl; 
    } 
} 

Dependencia:

public class TaskService { 

} 

prueba, grabados mockTaskService:

@RunWith(MockitoJUnitRunner.class) 
public class ReportServiceImplTestMockito { 

    @Mock 
    private TaskService  mockTaskService; 

    @InjectMocks 
    private ReportServiceImpl service; 


    @Test 
    public void testMockInjected() { 
     System.out.println(service.getTaskServiceImpl()); 
    } 
} 
+0

Hola, estoy usando Mockito 1.9 también ... – Noam

+1

Como digo, el código funciona para mí. ¿Puedes probar el código que publiqué (solo pequeños cambios)? –

+0

Hola Arend, disculpe la demora, pero su código también funciona para mí, he usado una importación worng para la anotación @Mock - import org.mockito.MockitoAnnotations; en lugar de importar org.mockito.Mock; – Noam