mockito 模拟Spring零部件

lfapxunr  于 11个月前  发布在  Spring
关注(0)|答案(1)|浏览(84)

我在用Mockito来模仿 Spring Bean 。
当我模拟一个接口时,它工作得很好。
在我们的应用程序中,有几个@Component bean不实现任何接口。
当我尝试模拟这样的组件时,spring上下文会尝试将属性注入到这些组件中。
Mockito不支持不实现任何接口的mocking spring组件吗?
按要求附上示例

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实现。

bkkx9g8r

bkkx9g8r1#

问题

你混合了很多框架和注解。Spring使用@Autowired。Mockito使用@Mock@InjectMocks。在测试中,您还使用了多种方法来配置应用程序上下文-@Configuration@ContextConfiguration(locations = { ... })-但这种方法并不适用。有关所有细节,请参见混合XML、Groovy脚本和带注解的类。
问题是,您是想使用mocks编写单元测试,还是想不使用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 { ... }

相关问题