2017-09-19 5 views
1

Ich habe den folgenden Service:Mock ein Dienst von einem Dienst in einem anderen Dienst Junit

@Service 
public class AccountServiceImpl implements AccountService { 

    @Autowired 
    protected ContractService contractService; 

    private void saveInCache(MultipartFile multipartFile) { 
     this.contractService.saveInCache(multipartFile); 
    } 
} 

und einen anderen Dienst

@Service 
public class ClientServiceImpl implements ClientService { 

    @Autowired 
    protected ContractService contractService; 

    private void getInfoOfFile(String multipartFileId) { 
     DocumentInfo document = this.contractService.getInfo(multipartFileId); 
     /// 
    } 
} 

und ich habe meine Junit

public class ClientControllerTest extends ApiWebTest { 

    @Mock 
    protected ContractService contractService; 

    @Autowired 
    @InjectMocks 
    protected ClientService clientService = new ClientServiceImpl(); 

    @Before 
    private void setup() { 
    MockitoAnnotations.initMocks(this); 
    } 

    @Test 
    private void testGetInfo() { 
    // Code 
    DocumentInfo multipartFile = new DocumentInfo(); 
    multipartFile.setMultipartFileId(1234); 
    when(this.contractService.getInfo(multipartFile.getMultipartFileId())).thenReturn(multipartFile); 

    // Test the Client service 'getInfoOfFile' method. 
    } 
} 

Wenn i Führen Sie diesen Test im Debug-Modus, sehe ich, dass die this.contractService.getInfo(multipartFileId); mir 'Null' zurückgibt.

Wohin gehe ich falsch im Spott.

Ich habe gerade den ContractService in meiner JUnit verspottet. Muss ich auch den AccountServiceImpl verspotten?

EDIT: die saveInCache und getInfo Methoden

private DocumentInfo getInfo(String documentId) { 
     if (StringUtils.isEmpty(documentId)) { 
      return null; 
     } 
     WriteLock lock = this.readWriteLock.writeLock(); 
     try { 
      lock.lock(); 
      DocumentInfo cachedDocument = this.documentCache.get(documentId); 
      return cachedDocument; 
     } finally { 
      if (lock != null) { 
       lock.unlock(); 
      } 
     } 
    } 

private DocumentInfo saveInCache(StreamingStorage document) { 
     if (document == null) { 
      throw new InvalidParameterException("Creative document is required to put into cache."); 
     } 
     WriteLock lock = this.readWriteLock.writeLock(); 
     try { 
      lock.lock(); 
      DocumentInfo newCachedDocument = this.documentCache.put(document.getDocumentId(), document); 
      return newCachedDocument; 
     } finally { 
      if (lock != null) { 
       lock.unlock(); 
      } 
     } 
    } 
+1

Sie brauchen @Autowired nicht für geschützten ClientService clientService; Auch anstelle des geschützten ClientService clientService; versuch mit - private ClientServiceImpl clientService – asg

+0

Auch getInfo von ContractService ist nicht sichtbar. Könnten Sie bitte diese Methode hinzufügen? – asg

+0

@asg Hinzugefügt die Methoden – Vishnukk

Antwort

0

Hinzufügen glaube ich Ihnen, sich mit der Erklärung des clientService sind widersprechen.

Sie haben:

@Autowired 
@InjectMocks 
protected ClientService clientService = new ClientServiceImpl(); 

Dies sollte eine autowired ClientService genannt clientService erstellen und die Mocks injizieren. Aber die = new ClientServiceImpl() wird dann überschreiben die Autowiring und erstellen Sie eine Plain Vanilla (ich denke!). Auch @Autowired und @InjectMocks werden nicht gleichzeitig benötigt - Sie möchten einen Dienst mit injizierten Mocks erstellen - kein autowired Objekt.

können Sie versuchen, Ändern Sie wie folgt testen:

@RunWith(MockitoJUnitRunner.class) 
public class ClientControllerTest extends ApiWebTest { 

    @Mock 
    protected ContractService contractService; 

    @InjectMocks 
    protected ClientService clientService; 

    @Test 
    private void testGetInfo() { 
    DocumentInfo multipartFile = new DocumentInfo(); 
    multipartFile.setMultipartFileId(1234); 
    when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile); 

    } 
} 

Hinzufügen @RunWith(MockitoJUnitRunner.class) bedeutet das alle Objekterstellung für jede weitere Arbeit von Ihnen, ohne die Notwendigkeit geschieht.

+0

Mit dem früher versucht. Immer noch kein Glück! – Vishnukk

+0

Ich habe ein größeres Beispiel hinzugefügt: Entfernen Sie den Autowired, und fügte ein Runwith hinzu. Das funktioniert für mich – robjwilkins

0

@InjectMocks erstellt eine Instanz der Klasse und injiziert die Mocks, die mit den @Mock Annotationen erstellt wurden. Sie müssen also die Instanz von ClientService nicht erstellen und entfernen Sie @Autowired darauf.

Sie können MockitoJUnitRunner anstelle von MockitoAnnotations.initMocks(this) verwenden. Der Code ist einfacher.

Testclass nach Änderungen:

@RunWith(MockitoJUnitRunner.class) 
public class ClientControllerTest extends ApiWebTest { 

    @Mock 
    private ContractService contractService; 

    @InjectMocks 
    private ClientService clientService; 

    @Test 
    private void testGetInfo() { 
     // Code 
     DocumentInfo multipartFile = new DocumentInfo(); 
     multipartFile.setMultipartFileId(1234); 

     when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile); 

     // Test the Client service 'getInfoOfFile' method. 
    } 
} 
0
 DocumentInfo multipartFile = new DocumentInfo(); 
    multipartFile.setMultipartFileId(1234); 
    when(this.contractService.getInfo(multipartFile)).thenReturn(multipartFile); 

Hier erwarten Sie multipartFile Instanz in Ihrem Mock, die seit nicht der Fall ist, da es eine weitere Instanz von DocumentInfo während des Tests sein (getInfo Methode sehen, die es schafft).

Sie sollten Ihre Mock ändern, so etwas zu sein:

when(this.contractService.getInfo(any())).thenReturn(multipartFile); 

In diesem Fall wird die Erwartung, gegen jede Instanz von Document statt Ihrem speziellen Fall angepasst werden, die Sie über Konstruktor multipartFile = new DocumentInfo();

Verwandte Themen