英文:
Why my Service unit test using mockito and model mapper is not failing?
问题
I am quite new to Spring and Mockito and I am trapped in one tutorial.
我对Spring和Mockito都很陌生,卡在了一个教程中。
I have a simple service which is fetching books from the repository.
我有一个简单的服务,从仓库中获取书籍。
Then I have a simple unit test for that service, with just one test.
然后,我为这个服务编写了一个简单的单元测试,只有一个测试。
This is my configuration for ModelMapper.
这是我的ModelMapper配置。
This is my Book entity class.
这是我的Book实体类。
This is my BookDto class.
这是我的BookDto类。
I don't know why my unit test is not failing, as it should because of this line.
我不知道为什么我的单元测试没有失败,它应该因为这一行而失败。
Because it should return the third book dto for each of the fetched books, so the assertions regarding the first and second fetched books should fail.
因为它应该为每一本获取的书返回第三本书的DTO,所以关于第一本和第二本获取的书的断言应该失败。
In the assertions of books fetched, I was using "books" instead of "fetchedBooks."
在关于获取的书籍的断言中,我使用了"books"而不是"fetchedBooks"。
But now, I get the following error when running the test.
但是现在,当运行测试时,我得到了以下错误。
Error message:
错误消息:
java.lang.AssertionError: Expecting actual not to be null.
java.lang.AssertionError: 期望实际值不为null。
At this line:
在这一行:
.hasFieldOrPropertyWithValue("title", "Dune")
英文:
I am quite new to Spring and Mockito and I am trapped in one tutorial.
I have a simple service which is fetching books from repository
@Service
public class BookService {
private BookRepository bookRepository;
private ModelMapper modelMapper;
public BookService(BookRepository bookRepository, ModelMapper modelMapper) {
this.bookRepository = bookRepository;
this.modelMapper = modelMapper;
}
public List<BookDto> fetchAllBooks() {
List<Book> books = bookRepository.findAll();
return books.stream()
.map(convertBookModelToBookDto())
.collect(Collectors.toList());
}
private Function<Book, BookDto> convertBookModelToBookDto() {
return book -> modelMapper.map(book, BookDto.class);
}
}
Then I have a simple unit test for that service, with just one test
@ExtendWith(MockitoExtension.class)
public class BookServiceTest {
@InjectMocks
private BookService bookService;
@Mock
private BookRepository bookRepository;
@Mock
private ModelMapper mapper;
private List<Book> books;
private List<BookDto> bookDtos;
@BeforeEach
public void setUp() {
Book book = getBook("Lord of the Rings", "J.R.R. Tolkien", 1951, "Trilogy");
Book book2 = getBook("Dune", "Frank Herbert", 1960, "Part I");
Book book3 = getBook("Hobbit", "J.R.R. Tolkien", 1947, "Story");
books = new ArrayList<>();
books.add(book);
books.add(book2);
books.add(book3);
BookDto bookDto = getBookDto("Lord of the Rings", "J.R.R. Tolkien", 1951, "Trilogy");
BookDto bookDto2 = getBookDto("Dune", "Frank Herbert", 1960, "Part I");
BookDto bookDto3 = getBookDto("Hobbit", "J.R.R. Tolkien", 1947, "Story");
bookDtos = new ArrayList<>();
bookDtos.add(bookDto);
bookDtos.add(bookDto2);
bookDtos.add(bookDto3);
MockitoAnnotations.openMocks(this);
}
/**
* Test of fetchAllBooks method, of class BookService.
*/
@Test
public void testFetchAllBooks() {
Book book = books.get(0);
// Mockito.doReturn(bookDtos.get(2)).when(mapper).map(book, BookDto.class);
// Mockito.doReturn(books).when(bookRepository).findAll();
Mockito.when(bookRepository.findAll()).thenReturn(books);
Mockito.when(mapper.map(book, BookDto.class))
.thenReturn(bookDtos.get(0), bookDtos.get(1), bookDtos.get(2));
List<BookDto> fetchedBooks = bookService.fetchAllBooks();
assertThat(fetchedBooks.size()).isEqualTo(3);
assertThat(fetchedBooks.get(0))
.hasFieldOrPropertyWithValue("title", "Lord of the Rings")
.hasFieldOrPropertyWithValue("author", "J.R.R. Tolkien")
.hasFieldOrPropertyWithValue("releaseYear", 1951)
.hasFieldOrPropertyWithValue("description", "Trilogy");
assertThat(fetchedBooks.get(1))
.hasFieldOrPropertyWithValue("title", "Dune")
.hasFieldOrPropertyWithValue("author", "Frank Herbert")
.hasFieldOrPropertyWithValue("releaseYear", 1960)
.hasFieldOrPropertyWithValue("description", "Part I");
assertThat(fetchedBooks.get(2))
.hasFieldOrPropertyWithValue("title", "Hobbit")
.hasFieldOrPropertyWithValue("author", "J.R.R. Tolkien")
.hasFieldOrPropertyWithValue("releaseYear", 1947)
.hasFieldOrPropertyWithValue("description", "Story");
}
private Book getBook(String title, String author, int year, String description) {
return Book.builder()
.author(author)
.title(title)
.releaseYear(year)
.description(description)
.build();
}
private BookDto getBookDto(String title, String author, int year, String description) {
return BookDto.builder()
.author(author)
.title(title)
.releaseYear(year)
.description(description)
.build();
}
}
This is my configuration for model mapper
@Configuration
public class ModelMapperConfiguration {
@Bean
public ModelMapper modelMapper() {
return new ModelMapper();
}
}
This is my Book entity class
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "books")
public class Book implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(columnDefinition = "NUMERIC(19,0)")
private Long id;
@Column(name = "title", nullable = false, unique = true)
private String title;
@Column(name = "description", nullable = false)
private String description;
@Column(name = "author", nullable = false)
private String author;
@Column(name = "release_year", nullable = false)
private Integer releaseYear;
}
This is my BookDto class
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class BookDto {
private Long id;
private String title;
private String description;
private String author;
private Integer releaseYear;
}
I dont know why my unit test is not failing, as it should because of this line
Mockito.doReturn(bookDtos.get(2)).when(mapper).map(book, BookDto.class);
because it should return the third book dto, for each of the fetched books, so the assertions regarding the first and second fetched books should fail...
I dont know what I am missing here.
Spring Boot 2.7.12
Mockito 5.3.1
Assertj 3.24.2
Model Mapper 3.1.1
JUnit 5
Java 17
Edit 1
In the assertions of books fetched I was using books, not fetchedBooks.
But now get following error when run test:
java.lang.AssertionError: Expecting actual not to be null
at this line:
.hasFieldOrPropertyWithValue("title", "Dune")
答案1
得分: 0
感谢您的评论,问题确实是我对Mockito的误解。
以下是已修复的测试,现在按照我的期望工作:
@Test
public void testFetchAllBooks() {
Mockito.doReturn(bookDtos.get(0))
.when(mapper).map(books.get(0), BookDto.class);
Mockito.doReturn(bookDtos.get(1))
.when(mapper).map(books.get(1), BookDto.class);
Mockito.doReturn(bookDtos.get(2))
.when(mapper).map(books.get(2), BookDto.class);
Mockito.doReturn(books)
.when(bookRepository).findAll();
List<BookDto> fetchedBooks = bookService.fetchAllBooks();
assertThat(fetchedBooks.size()).isEqualTo(3);
assertThat(fetchedBooks.get(0))
.hasFieldOrPropertyWithValue("title", "Lord of the Rings")
.hasFieldOrPropertyWithValue("author", "J.R.R. Tolkien")
.hasFieldOrPropertyWithValue("releaseYear", 1951)
.hasFieldOrPropertyWithValue("description", "Trilogy");
assertThat(fetchedBooks.get(1))
.hasFieldOrPropertyWithValue("title", "Dune")
.hasFieldOrPropertyWithValue("author", "Frank Herbert")
.hasFieldOrPropertyWithValue("releaseYear", 1960)
.hasFieldOrPropertyWithValue("description", "Part I");
assertThat(fetchedBooks.get(2))
.hasFieldOrPropertyWithValue("title", "Hobbit")
.hasFieldOrPropertyWithValue("author", "J.R.R. Tolkien")
.hasFieldOrPropertyWithValue("releaseYear", 1947)
.hasFieldOrPropertyWithValue("description", "Story");
}
希望这对您有所帮助。
英文:
Thanks for comments, indeeed the problem was with my misunderstanding of mockito.
Here is the fixed test which is now working as I expected.
@Test
public void testFetchAllBooks() {
Mockito.doReturn(bookDtos.get(0))
.when(mapper).map(books.get(0), BookDto.class);
Mockito.doReturn(bookDtos.get(1))
.when(mapper).map(books.get(1), BookDto.class);
Mockito.doReturn(bookDtos.get(2))
.when(mapper).map(books.get(2), BookDto.class);
Mockito.doReturn(books)
.when(bookRepository).findAll();
List<BookDto> fetchedBooks = bookService.fetchAllBooks();
assertThat(fetchedBooks.size()).isEqualTo(3);
assertThat(fetchedBooks.get(0))
.hasFieldOrPropertyWithValue("title", "Lord of the Rings")
.hasFieldOrPropertyWithValue("author", "J.R.R. Tolkien")
.hasFieldOrPropertyWithValue("releaseYear", 1951)
.hasFieldOrPropertyWithValue("description", "Trilogy");
assertThat(fetchedBooks.get(1))
.hasFieldOrPropertyWithValue("title", "Dune")
.hasFieldOrPropertyWithValue("author", "Frank Herbert")
.hasFieldOrPropertyWithValue("releaseYear", 1960)
.hasFieldOrPropertyWithValue("description", "Part I");
assertThat(fetchedBooks.get(2))
.hasFieldOrPropertyWithValue("title", "Hobbit")
.hasFieldOrPropertyWithValue("author", "J.R.R. Tolkien")
.hasFieldOrPropertyWithValue("releaseYear", 1947)
.hasFieldOrPropertyWithValue("description", "Story");
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论