繁体   English   中英

如何在 Spring 引导单元测试中使用依赖注入?

[英]How to use Dependency Injection with Spring Boot Unit Testing?

是否可以使用 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 (或类似库)测试服务层 mocking 存储库层,并使用@DataJpaTest测试存储库层。

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

服务 Class

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

服务测试 Class

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM