java如何使用SpringBoot 2运行单元测试
我有以下测试:
@SpringBootTest
@ExtendWith(SpringExtension.class)
class BookServiceImplTest {
@MockBean
private BookRepository bookRepository;
@MockBean
private LibraryService libraryService;
@Autowired
private BookServiceImpl bookService;
@Test
void create() {
BookRequestDTO bookRequestDTO = new BookRequestDTO();
Library library = new Library();
Book expectedBook = new Book();
when(libraryService.getById(bookRequestDTO.getLibraryId()))
.thenReturn(library);
when(bookRepository.save(any(Book.class)))
.thenReturn(expectedBook);
Book actualBook = bookService.create(bookRequestDTO);
assertEquals(expectedBook, actualBook);
}
}
它可以运行,但我想知道是否有一种方法可以作为单元测试而不是集成测试来运行它,并且仍然使用@MockBean@Autowired。还是我遗漏了什么
我试着只留下@ExtendWith(SpringExtension.class),但我得到了一个关于bookserviceimplbean的异常,没有找到
我知道如何使用MockitoExtension和@Mock、@InjectMocks来实现这一点,但我想知道是否有一种更好的SpringBoot方式来实现这一点
# 1 楼答案
删除
@SpringBootTest
,这将加载整个上下文并降低测试速度。@MockBean
的作用是从指定的bean创建一个模拟,并将其添加到上下文中。因为没有上下文运行,所以使用@MockBean
用
@RunWith(SpringRunner.class)
对于注入依赖项,显式地创建配置文件和模拟bean并使用它们创建目标bean是一个很好的实践。假设您使用的是基于构造函数的注入:
然后将测试类编写为:
# 2 楼答案
您可以通过四个步骤进行单元测试:
@SpringBootTest
注释,因为它会使整个Spring上下文旋转起来,这对于模拟所有协作者的单元测试没有用处@Autowired
注释,并添加一个@BeforeEach
设置方法,在该方法中初始化bookService
传递bookRepository
和libraryService
作为参数MockitoExtension
而不是SpringExtension
。在这里,我假设您能够使用像Mockito这样的库来模拟您的合作者@Mock
而不是@MockBean
,因为我们正在手动初始化bookService
,所以不需要处理springbean在第一个问题上再补充一点:
@Mockbean
和@Autowired
是对集成测试有意义的注释,因为它们处理bean的模拟和注入。单元测试应该孤立地考虑这个类,嘲笑与其他类的交互,因此不需要旋转应用程序上下文并设置bean。p>