web-dev-qa-db-fra.com

Utilisation de @Mock et @InjectMocks

J'étudie actuellement le framework Mockito et j'ai créé plusieurs cas de test en utilisant Mockito. Mais ensuite j'ai lu qu'au lieu d'invoquer mock (SomeClass. Class) je peux utiliser le @Mock Et le @InjectMocks - La seule chose que je dois faire est d'annoter ma classe de test avec @RunWith(MockitoJUnitRunner.class) ou utilisez la MockitoAnnotations.initMocks(this); dans la méthode @Before.

Mais cela ne fonctionne pas - Il semble que le @Mock Ne fonctionnera pas! Voici mes 2 révisions de codes - une utilisant les annotations et une sans.

Qu'est-ce que je fais 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
}

Comme je l'ai dit - ce travail est formidable. Mais ce qui suit n'est pas:

@RunWith(MockitoJUnitRunner.class)
public class ReportServiceImplTestMockito {

     @Mock 
     private TaskService      mockTaskService;

     @InjectMocks 
     private ReportServiceImpl service;

         // Some tests
}

Et voici la classe 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'est-ce que je rate?

35
Noam

O.K, j'ai eu mon erreur !!! J'ai utilisé le @InjectMocks mais a initialisé la même variable dans la méthode init () ... Donc, ce qui s'est passé, c'est que mockito a injecté les objets fictifs à ma variable - mais quelques secondes plus tard, je l'ai parcouru - initialisant cette même variable !!!

27
Noam

Votre code fonctionne bien pour moi en utilisant Mockito 1.9.

En utilisant une version 1.8+ de Mockito, j'obtiens un message d'erreur très spécifique me disant exactement comment résoudre le problème. Comme le suggère le codeur php: pour Mockito 1.8+, vous devez initialiser le champ.

Avez-vous vu ce message ou tout autre message d'erreur?

Modifier:

Le code suivant fonctionne pour moi. Petits changements:

  • Annotations Spring supprimées
  • Interface supprimée
  • Getter ajouté
  • Ajouté TaskService vide
  • Test ajouté avec System.out.println

Cela produit-il une erreur pour vous? :

Un service:

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;
    }
}

Dépendance:

public class TaskService {

}

Test, imprime mockTaskService:

@RunWith(MockitoJUnitRunner.class)
public class ReportServiceImplTestMockito {

    @Mock
    private TaskService       mockTaskService;

    @InjectMocks
    private ReportServiceImpl service;


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

Je ne suis pas sûr, mais essayez de créer manuellement une nouvelle instance de ReportServiceImpl (comme vous l'avez fait dans l'exemple de travail):

 @InjectMocks 
 private ReportServiceImpl service = new ReportServiceImpl();
3
Slava Semushin