我想为我的 BookService 编写一个测试。这就是那个测试。我不知道为什么我总是收到以下错误:
org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter
[com.mrfisherman.library.service.domain.BookService bookService] in constructor
[public com.mrfisherman.library.service.domain.BookServiceTest(com.mrfisherman.library.service.domain.BookService,
com.mrfisherman.library.persistence.repository.BookRepository)].
如您所见,我在这里没有使用参数化测试。提前谢谢你!
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = Server.class)
class BookServiceTest {
private final BookService bookService;
private final BookRepository bookRepository;
public BookServiceTest(BookService bookService, BookRepository bookRepository) {
this.bookService = bookService;
this.bookRepository = bookRepository;
}
@Test
void saveBook() {
//given
Book book = new Book();
book.setTitle("Book 1");
book.setPublishYear(1990);
book.setType(BookFormat.REAL);
book.setIsbn("1234567890");
book.setDescription("Very good book");
book.setNumberOfPages(190);
book.setSummary("Very short summary");
book.setCategories(Set.of(new Category("horror"), new Category("drama")));
//when
bookService.saveBook(book);
//then
Optional<Book> loaded = bookRepository.findById(book.getId());
assertThat(loaded).isPresent();
}
}
在 JUnit Jupiter 中,每当测试类构造函数、生命周期方法(例如
ParameterResolutionException
)或测试方法声明无法由已注册的@BeforeEach
扩展之一解析的参数时,就会抛出ParameterResolver
。
因此,即使您没有使用
ParameterResolutionException
方法,也可以抛出 @ParameterizedTest
。
使用
@SpringBootTest
时,SpringExtension
会自动为您注册。 SpringExtension
实现了来自 JUnit Jupiter 的 ParameterResolver
扩展 API,这样您就可以将 ApplicationContext
中的 bean 注入到测试类中的构造函数和方法中。
解决问题的最简单方法是用
BookServiceTest
注释 @Autowired
构造函数。
有关更多信息和替代方法,请查看 Dependency Injection with
SpringExtension
Spring 参考文档的部分。
它是参数化的。测试框架应该如何创建
BookServiceTest
类的新实例?
通常,测试类有一个无参数的构造函数(此时,框架可以创建一个新的实例,而不需要任何额外的信息,比如“我如何获得一个 bookService 的实例来传递给这个构造函数?”)。
该错误也发生在 junit5 测试中,使用 jboss Weld 容器 初始化。如果您在测试上没有附加注释,则 @ParameterizedTest 方法将失败。请使用 @ExplicitParamInjection 修复它。
@EnableWeld
@ExplicitParamInjection // that should be put to prevent error in test run
class MyCustomTest {
@WeldSetup
public WeldInitiator weld = WeldInitiator.from()...........build();
@CsvSource(value = {1, 2, 3})
@ParameterizedTest
void getEventsByFilter(int inputValue) {
// do some stuff with inputValue
}
}
}