我想从控制器和服务层测试相同的方法。问题是:为什么我必须在控制器中使用@MockBean
注释,为什么不为BookFindOperationsService bookService
使用@Mock
注释。对于服务,同样的问题是,为什么我需要@Mock
存储库,为什么不使用@MockBean
?你能告诉我这两者的区别吗?
这里是控制器:
@RestController
public class BookFindOperationsController {
private final BookFindOperationsService bookService;
@Autowired
public BookFindOperationsController(BookFindOperationsService bookService) {
this.bookService = bookService;
}
@GetMapping("/books/author/{authorID}")
public List<Book> findBooksByAuthor(@PathVariable String authorID) {
return bookService.findBooksByAuthor(authorID);
}
}
这里是服务类:
@Service
public class BookFindOperationsService {
private final BookRepository bookRepository;
@Autowired
public BookFindOperationsService(BookRepository bookRepository) {
this.bookRepository = bookRepository;
}
public List<Book> findBooksByAuthor(String authorID) {
return bookRepository.findByAuthorAllIgnoreCase(authorID);
}
}
服务测试:
@RunWith(MockitoJUnitRunner.class)
public class BookFindOperationsServiceTest {
@Mock
BookRepository bookRepository;
@InjectMocks
BookFindOperationsService bookFindOperationsService;
@Test
public void findBooksByAuthor() {
Book book = createDummyBook();
List<Book> books = new ArrayList<>();
books.add(book);
when(bookRepository.findByAuthorAllIgnoreCase("Henryk Sienkiewicz")).thenReturn(books);
assertEquals(1, bookFindOperationsService.findBooksByAuthor("Henryk Sienkiewicz").size());
}
private Book createDummyBook() {
return new Book("W pustyni i w puszczy", "Henryk Sienkiewicz", "dramat", true);
}
控制器测试:
@RunWith(SpringRunner.class)
@WebMvcTest(BookFindOperationsController.class)
public class BookFindOperationsControllerTest {
@Autowired
MockMvc mockMvc;
@MockBean
BookFindOperationsService bookService;
@Test
public void findBooksByAuthor() throws Exception {
List<Book> books = new ArrayList<>();
Book book = new Book("W pustyni i w puszczy", "Henryk Sienkiewicz", "dramat", true);
books.add(book);
when(bookService.findBooksByAuthor("Henryk Sienkiewicz")).thenReturn(books);
String expected = "[{\"id\":0,\"title\":\"W pustyni i w puszczy\",\"author\":\"Henryk Sienkiewicz\",\"category\":\"dramat\",\"available\":true}]";
MvcResult mvcResult = mockMvc.perform(get("/books/author/Henryk Sienkiewicz")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8))
.andReturn();
String content = mvcResult.getResponse().getContentAsString();
assertEquals(expected, content);
verify(bookService, times(1)).findBooksByAuthor(anyString());
}
@MockBean用于向Spring应用程序上下文添加mock对象。模拟将替换应用程序上下文中任何现有的相同类型的bean。你可以在集成测试中使用它
@moock在单元测试中用于替换某些实现。看这儿
使用@MockBean时的一个重要注意事项。在这种情况下,Spring上下文不会缓存,如果您有许多集成测试,上下文的初始化可能会花费大量时间。
@Mock
和@MockBean
之间的主要区别在于前者属于Mockito框架,后者属于Mockito下的Spring测试框架。
@MockBean
用模拟Bean创建/替换Spring Bean,以便其他Spring加载的Bean(控制器等)可以使用它。这就是为什么在使用MockMvc时需要它。执行
。
@Mock
注释不适用于Spring上下文。它只会尝试将标记有此注释的模拟对象映射到标记有@InjectMocks
的对象的属性。
更新
当使用@WebMvcTest(BookFindOperationsController.class)
时,将创建一个Spring上下文,该上下文包含所有必要的bean,以支持作为Web应用程序运行BookFindOperationsController
类。这意味着任何拦截器、过滤器、转换器也需要在Spring上下文中加载。这个Spring上下文还将加载自己的BookFindOperationsService
,它不是一个模拟的,而是一个实际的实现。但是为了进行测试,你需要一个Mock,这就是为什么你用@MockBean
注释这个bean,以指示Spring上下文使用模拟的bean而不是实际的bean。这是一个集成测试,因为您可以测试所有组件是否正确地协同工作。
使用@RunWith(MockitoJUnitRunner.class)
时,不会隐式创建任何Spring上下文。因此,您不能使用@MockBean
,因为没有可模拟的Spring bean。这是一个单元测试,因为您在模拟BookRepository
时只测试BookFindOperationsService
,而没有实际在数据库中保存任何内容。
希望这能解释清楚。
问题内容: 我有以下情况: controller.js controllerSpec.js 错误: 我也尝试过类似的方法,但没有成功: 我该如何解决?有什么建议? 问题答案: 有两种方法(或肯定有更多方法)。 想象一下这种服务(无论它是工厂都没关系): 使用此控制器: 一种方法是使用要使用的方法创建对象并对其进行监视: 然后,将其作为dep传递给控制器。无需注入服务。那可行。 另一种方法是模拟
我已经开始考虑在我的项目中围绕一些业务逻辑添加一些单元测试。 我想测试的第一个方法是服务层中的一个方法,它返回给定节点的子节点列表。 该方法如下所示: 我想象这样的测试方法是提供一个假树结构,然后测试提供节点是否返回正确的子节点。 ssdsContext是一个对象上下文。 我已经看到可以为提取和接口如何模拟ObjectContext或ObjectQuery 我还读到,as Entity Frame
本文向大家介绍AngularJS 单元测试控制器,包括了AngularJS 单元测试控制器的使用技巧和注意事项,需要的朋友参考一下 示例 控制器代码: 考试: 跑!
好的,我试过了。但我不能把我的头缠在这上面。 我有控制器 Svc是ExtController抽象类中的服务类型的公共属性,它反过来扩展Controller类 下面是使用NUnit的单元测试代码 问题是,当调用Create方法时,它需要使用Svc来处理操作,所以我想我必须嘲笑它!但我不知道怎么做。 我应该嘲笑控制器吗!但我不能,因为它是一个密封的类!或者是ExtController!我迷路了,需要指
如何为GraphQL编写单元测试?我正在使用apollo服务器、graphql-tester和graphql。
问题内容: 我有一个ParseService,我想对其进行模拟以测试使用它的所有控制器,我一直在阅读有关茉莉花间谍的信息,但对我来说仍然不清楚。谁能给我一个关于如何模拟定制服务并在Controller测试中使用它的示例吗? 现在,我有一个使用服务插入书的控制器: 服务是这样的: 到目前为止,我的测试如下所示: 现在测试失败: 我做错了什么? 问题答案: 我做错的是没有在beforeEach中将模拟