2017-02-05 3 views
3

Ich benutze Mockito, um Frühlingsbohnen zu verspotten.Mock Spring Komponente

Es funktioniert gut, wenn ich eine Schnittstelle vortäusche.

In unserer Anwendung gibt es nur wenige @Component-Beans, die keine Schnittstelle implementieren.

Wenn ich versuche, solche Komponente zu verspotten, versucht der Spring-Kontext, die Eigenschaften in diesen Komponenten zu injizieren.

Unterstützt Mockito keine spöttischen Federkomponenten, die keine Schnittstelle implementieren?

Befestigt Beispiel als

angefordert
public interface EmployeeInterface { 
    public Long saveEmployee(Employee employee); 
} 

@Component 
public class EmployeeImpl implements EmployeeInterface { 

    @Autowired 
    public EmailSender emailSender 

    public Long saveEmployee(Employee employee) { 
     ... 
    } 
} 

public interface EmailSender { 
    public boolean sendEmail(Email email); 
} 

@Component 
public class EmailSenderImpl implements EmailSender { 

    @Autowired 
    MailServerInfo MailServerInfo; 

    public boolean sendEmail(Email email) { 
     ... 
    } 
} 

public interface MailServerInfo { 
    public String getMailServerDetails(); 
} 

@Component 
public class MailServerInfoImpl { 

    public String getMailServerDetails() { 
     ... 
    } 
} 

@Profile("Security-test") 
@Configuration 
public class SecurityTestMockConfiguration { 

    @Bean 
    @Primary 
    public EmailSender emailSender() { 
     return Mockito.mock(EmailSender.class); 
    } 
} 

@ActiveProfiles("Security-test") 
@RunWith(PowerMockRunner.class) 
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:context-test.xml" }) 
public class MyTest { 

    @Autowired 
    EmployeeInterface employeeInterface; 

    @Test 
    public void testSaveEmployee() { 
     employeeInterface.saveEmployee(employee); 
    } 
} 

Im obigen Beispiel, wenn ich EmailSender mit Mockito verspotten funktioniert es völlig in Ordnung.

Im folgenden Szenario ist EmailSender eine Spring-Komponente, die keine Schnittstelle implementiert. Im folgenden Fall erhalte ich einen Fehler während der automatischen Verdrahtung.

public interface EmployeeInterface { 
    public Long saveEmployee(Employee employee); 
} 

@Component 
public class EmployeeImpl implements EmployeeInterface { 

    @Autowired 
    public EmailSender emailSender 

    public Long saveEmployee(Employee employee) { 
     ... 
    } 
} 

@Component 
public class EmailSender { 

    @Autowired 
    MailServerInfo MailServerInfo; 

    public boolean sendEmail(Email email) { 
     ... 
    } 
} 

public interface MailServerInfo { 
    public String getMailServerDetails(); 
} 

@Component 
public class MailServerInfoImpl { 

    public String getMailServerDetails() { 
     ... 
    } 
} 

@Profile("Security-test") 
@Configuration 
public class SecurityTestMockConfiguration { 

    @Bean 
    @Primary 
    public EmailSender emailSender() { 
     return Mockito.mock(EmailSender.class); 
    } 
} 

@ActiveProfiles("Security-test") 
@RunWith(PowerMockRunner.class) 
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "classpath:context-test.xml" }) 
public class MyTest { 

    @Autowired 
    EmployeeInterface employeeInterface; 

    @Test 
    public void testSaveEmployee() { 
     employeeInterface.saveEmployee(employee); 
    } 
} 

Im zweiten Szenario schlägt die autowiring weil EmailSender nicht MailServerInfo Implementierung finden konnten.

+1

Bitte fügen Sie Ihre Testklasse an –

+0

Angeschlossen die Testklasse – lives

+0

Bitte geben Sie context-test.xml an. –

Antwort

3

Probleme

Sie mischen Frameworks und Anmerkungen ziemlich viel. Der Frühling verwendet @Autowired. Mockito verwendet @Mock und @InjectMocks. Sie können den Anwendungskontext auch auf verschiedene Arten in den Tests konfigurieren - und @ContextConfiguration(locations = { ... }) -, die nicht auf diese Weise funktionieren. Alle Details finden Sie unter Mixing XML, Groovy scripts, and annotated classes.

Die Frage ist, wenn Sie einen Komponententest mit Mocks schreiben möchten oder wenn Sie einen Integrationstest schreiben möchten, der keine Mocks, sondern einen Spring-Kontext verwendet?

Einheit Tests

Wenn Sie verspotten wollen EmailSender dann @Mock Anmerkung des Mockito. Sie können dann Mockito die Abhängigkeiten von EmployeeImpl über @InjectMocks injizieren lassen.

@Mock 
EmailSender emailSender; 

@InjectMocks 
EmployeeImpl employee; 

Sie können auch einen Blick auf ein Tutorial haben wie diese https://dzone.com/articles/use-mockito-mock-autowired

Integrationstests

Wenn Sie einen Integrationstest verwenden entweder

@Configuration 
public class TestConfiguration { ... } 

@ContextConfiguration(classes = { TestConfiguration.class }) 
public class MyTest { ... } 

oder

schreiben wollen
@ContextConfiguration(locations = { "classpath:context-test.xml" }) 
public class MyTest { ... } 
+0

danke für die Klarstellung. Das war nützlich. Ich möchte einen Integrationstest für einen Frühlingskontext schreiben. Es wird eine verschachtelte Autowiring von mehreren Beans innerhalb des Anwendungskontexts geben. Durch die Verwendung der Annotation ActiveProfile und @primary kann ich solche Beans erfolgreich im Anwendungskontext vortäuschen. In meinem Beispiel greife ich von der Junit-Testklasse nur auf das EmployeeInterface zu, das intern Abhängigkeiten von anderen Beans hat. Ich erhalte nur Fehler, wenn ich versuche, eine Spring-Komponente zu verspotten, die keine Schnittstelle implementiert. Ansonsten funktioniert es. Hoffe ich habe mein Szenario klar gemacht. – lives

Verwandte Themen