Tho*_*ulé 2 java junit spring unit-testing mockito
我想使用Spring + JUnit + Mockito测试一个类,但我无法使其正常工作.
假设我的班级引用了一项服务:
@Controller
public class MyController
{
@Autowired
private MyService service;
@PostConstruct
public void init() {
service.whatever();
}
public void doSomething() {
service.create();
}
}
Run Code Online (Sandbox Code Playgroud)
此服务引用了一个存储库:
@Service
public class MyService {
@Autowired
private MyRepository repository;
public void whatever() {}
public void create() {
repository.save();
}
}
Run Code Online (Sandbox Code Playgroud)
在测试MyController类时,我希望模拟该服务.问题是:即使服务被模拟,Spring也会尝试在mock中注入存储库.
这就是我做的.测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { MyControllerTestConfiguration.class })
public class MyControllerTest {
@Autowired
private MyController myController;
@Test
public void testDoSomething() {
myController.doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
配置类:
@Configuration
public class MyControllerTestConfiguration {
@Bean
public MyController myController() {
return new MyController();
}
@Bean
public MyService myService() {
return Mockito.mock(MyService.class);
}
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [test.test.MyRepository] found for dependency
我尝试使用Mockito的@InjectMocks注释来初始化模拟但是这会失败,因为在模拟@PostConstruct注入之前调用该方法,生成一个NullPointerException.
我不能简单地模拟存储库,因为在现实生活中会让我模拟很多类...
谁可以帮我这个事?
使用构造函数而不是字段注入.这使得测试变得更加容易.
@Service
public class MyService {
private final MyRepository repository;
@Autowired
public MyService(MyRepository repository) {
this.repository = repository;
}
public void whatever() {}
public void create() {
repository.save();
}
}
Run Code Online (Sandbox Code Playgroud)
-
@Controller
public class MyController {
private final MyService service;
@Autowired
public MyController(MyService service) {
this.service = service;
}
@PostConstruct
public void init() {
service.whatever();
}
public void doSomething() {
service.create();
}
}
Run Code Online (Sandbox Code Playgroud)
这有几个好处:
NullPointerException.[依赖项的实例字段]可以是final,因此1)它们不会被意外修改,2)任何读取该字段的线程都将读取相同的值.
丢弃@Configuration该类并编写如下测试:
@RunWith(MockitoJUnitRunner.class)
public class MyControllerTest {
@Mock
private MyRepository repository;
@InjectMocks
private MyService service;
@Test
public void testDoSomething() {
MyController myController = new MyController(service);
myController.doSomething();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1670 次 |
| 最近记录: |