如何在Spring Boot单元测试中使用依赖注入



是否可以使用Spring Boot在单元测试中使用依赖项注入?对于集成测试@SpringBootTest,启动整个应用程序上下文和容器服务。但是,是否可以在单元测试粒度上启用依赖项注入功能?

这是的示例代码

@ExtendWith(SpringExtension.class)
public class MyServiceTest {

@MockBean
private MyRepository repo;

@Autowired
private MyService service; // <-- this is null

@Test
void getData() {
MyEntity e1 = new MyEntity("hello");
MyEntity e2 = new MyEntity("world");

Mockito.when(repo.findAll()).thenReturn(Arrays.asList(e1, e2));

List<String> data = service.getData();

assertEquals(2, data.size());
}
}
@Service
public class MyService {

private final MyRepository repo; // <-- this is null

public MyService(MyRepository repo) {
this.repo = repo;
}

public List<String> getData() {
return repo.findAll().stream()
.map(MyEntity::getData)
.collect(Collectors.toList());
}
}

还是应该将SUT(服务类(作为POJO进行管理,并手动注入模拟的依赖关系?我想让测试保持快速,但尽量减少样板代码。

正如评论中提到的@M.Deinum,单元测试不应该使用依赖注入。使用Mockito(和Junit5(:模拟MyRepository并注入MyService

@ExtendWith(MockitoExtension.class)
public class MyServiceTest {
@InjectMocks
private MyService service;
@Mock
private MyRepository repo;
@Test
void getData() {
MyEntity e1 = new MyEntity("hello");
MyEntity e2 = new MyEntity("world");
Mockito.when(repo.findAll()).thenReturn(Arrays.asList(e1, e2));
List<String> data = service.getData();
assertEquals(2, data.size());
}
}

如果要测试存储库,请使用@DataJpaTest。来自文档:

使用此注释将禁用完全自动配置仅应用与JPA测试相关的配置。

@DataJpaTest
public class MyRepositorTest {
@Autowired
// This is injected by @DataJpaTest as in-memory database
private MyRepository repo;
@Test
void testCount() {
repo.save(new MyEntity("hello"));
repo.save(new MyEntity("world"));
assertEquals(2, repo.count());
}
}

总之,建议的方法是用Mockito(或类似的库(测试服务层模拟存储库层,并用@DataJpaTest测试存储库层。

您尚未在MyRepository的服务中添加@Autowired

服务类别

@Service
public class MyService {

private final MyRepository repo; // <-- this is null

@Autowired
public MyService(MyRepository repo) {
this.repo = repo;
}

public List<String> getData() {
return repo.findAll().stream()
.map(MyEntity::getData)
.collect(Collectors.toList());
}
}

服务测试类

@ExtendWith(MockitoExtension.class)
public class MyServiceTest {

@Mock
private MyRepository repo;

@InjectMocks
private MyService service;

@Test
void getData() {
MyEntity e1 = new MyEntity("hello");
MyEntity e2 = new MyEntity("world");

Mockito.when(repo.findAll()).thenReturn(Arrays.asList(e1, e2));

List<String> data = service.getData();

assertEquals(2, data.size());
}
}

最新更新