2012-01-31 1 views
32

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

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 - cela fonctionne très bien. Mais la coutume suivante:

@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 manque?

+0

Cela me semble OK, à première vue. Qu'est-ce qui ne va pas pour toi? –

+1

@Noam Êtes-vous sûr d'utiliser les bonnes importations? – Brice

+0

David - J'obtiens une exception NullPointerException. Et Brice, je crois que j'utilise les bonnes importations - ici elles sont 'import org.jmock.auto.Mock; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.MockitoAnnotations; import org.mockito.runners.MockitoJUnitRunner; ' – Noam

Répondre

24

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

3

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

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

Ce n'est plus nécessaire puisque Mockito 1.9 à l'exception du cas de bordure. – Brice

+1

Si vous utilisez 1.8, vous devez l'instancier dans l'initialiseur ou dans le constructeur, sauf si vous utilisez 'MockitoAnnotations.initMocks (this)' dans ce cas, vous devez l'instancier avant de l'appeler. – jhericks

+3

D'abord, merci pour les réponses. mais utiliser MockitoAnnotations.initMocks (this) n'est pas nécessaire puisque j'ai utilisé @RunWith (MockitoJUnitRunner.class). – Noam

12

Votre code fonctionne bien pour moi en utilisant Mockito 1.9. En utilisant une version 1.8+ de Mockito, je reçois 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 un autre?

Edit:

Le code suivant fonctionne pour moi. De petits changements:

  • Suppression des annotations de printemps
  • Removed Interface
  • Ajouté Getter
  • Ajouté vide TaskService
  • Test Ajouté avec System.out.println

-t-il produit une erreur pour vous? :

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, impressions 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

Salut, J'utilise Mockito 1.9 aussi ... – Noam

+1

Comme je le dis, le code fonctionne pour moi. Pouvez-vous tester le code que j'ai posté (petits changements seulement)? –

+0

Salut Arend, désolé pour le retard - mais votre code fonctionne pour moi aussi, j'ai utilisé une importation usée pour l'annotation @Mock - import org.mockito.MockitoAnnotations; au lieu d'importer org.mockito.Mock; – Noam