2017-02-05 84 views
3

我正在使用Mockito模擬彈簧豆。模擬彈簧組件

它可以正常工作,當我嘲笑一個接口。

在我們的應用程序中,很少有@Component bean沒有實現任何接口。

當我嘗試模擬這樣的組件時,spring上下文嘗試在這些組件內注入屬性。

Mockito不支持不實現任何接口的模擬彈簧組件嗎?

附例的要求

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

在上面的例子,如果我使用它的Mockito工作完全正常嘲笑EmailSender。

在下面的場景中,EmailSender是一個沒有實現任何接口的Spring組件。在下面的情況下,在自動佈線過程中出現錯誤。

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

在第二種情況下,自動裝配因爲EmailSender找不到MailServerInfo執行失敗。

+1

請附上您的測試類 –

+0

附上測試類 – lives

+0

請提供context-test.xml。 –

回答

3

問題

你混合框架和註釋不少。 Spring使用@Autowired。 Mockito使用@Mock@InjectMocks。您還可以使用多種方式在測試中配置您的應用程序上下文 - @Configuration@ContextConfiguration(locations = { ... }) - 這不適用於此方式。所有的細節見Mixing XML, Groovy scripts, and annotated classes

問題是如果你想使用mock編寫單元測試,或者如果你想編寫一個不使用mocks而是使用Spring上下文的集成測試?如果你想嘲笑EmailSender然後使用的Mockito的@Mock註釋

單元測試

。然後您可以讓Mockito通過@InjectMocks注入EmployeeImpl的依賴關係。

@Mock 
EmailSender emailSender; 

@InjectMocks 
EmployeeImpl employee; 

你也可以看看這樣https://dzone.com/articles/use-mockito-mock-autowired

集成教程測試

如果你想要寫一個集成測試兼用

@Configuration 
public class TestConfiguration { ... } 

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

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

感謝您的澄清。這很有用。我想寫一個春季上下文的集成測試。應用程序上下文中將嵌套自動裝配幾個bean。通過使用ActiveProfile和@primary註釋,我能夠在應用程序上下文中成功模擬這些bean。在我的例子中,從junit測試類中,我只訪問EmployeeInterface,它內部依賴於其他bean。只有當我試圖模擬一個沒有實現接口的Spring組件時,我纔會出錯。否則它的作品。希望我已經明確了我的情況。 – lives