java - MockMvc 和 Mockito - java.lang.AssertionError : JSON path "$" Expected: a collection with size <2> but: collection size was <0>

标签 java spring-boot spring-boot-test mockmvc

我不知道为什么会在这里收到此错误。有什么想法吗?

这是我的存储库代码

package movieweb.movies.repository;

import movieweb.movies.models.Movies;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MoviesRepository extends CrudRepository<Movies, Integer> {
}

这是我的 Controller 代码。

package movieweb.movies.controllers;
import movieweb.movies.models.Movies;
import movieweb.movies.models.UserMovies;
import movieweb.movies.repository.MoviesRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;

import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ResponseStatusException;

@RestController
public class MoviesController {

    @Autowired
    private MoviesRepository moviesRepository;
    @Autowired
    private RestTemplate restTemplate;

    @CrossOrigin
    @GetMapping(path = "/movies")
    public  List<Movies> movies(){
        List<Movies> allMovies = (List<Movies>) moviesRepository.findAll();
        if (!allMovies.isEmpty()){
            return allMovies;
        } else {
            throw new ResponseStatusException(
                    HttpStatus.NOT_FOUND, "Movies not found"
            );
        }


    }

//    @CrossOrigin
//    @RequestMapping(path = "movies/user/{id}")
//    public List<Movies> movie(@PathVariable("id") int id){
//        return this.movies().stream().map(movie -> {
//            Users[] user = restTemplate.getForObject("http://127.0.0.1:8082/users/" + id, Users[].class);
//            return new Movies(movie.getMovieId(), movie.getMovieName(), "Description");
//        })
//                .collect(Collectors.toList());
//    }

    @CrossOrigin
    @GetMapping(path="/movie/{id}")
    public  Movies getMovie(@PathVariable Integer id){
        return moviesRepository.findById(id)
                .orElseThrow(() -> new ResponseStatusException(
                HttpStatus.NOT_FOUND, "Movie not found"
        ) );
    }

    @CrossOrigin
    @DeleteMapping("/movie/delete/{id}")
    void deleteMovie(@PathVariable Integer id) {
        moviesRepository.deleteById(id);
    }

    @CrossOrigin
    @PutMapping("/movie/update/{id}")
    Movies updateMovie(@RequestBody Movies updateMovie, @PathVariable Integer id) {

        return moviesRepository.findById(id)
                .map(Movies -> {
                    Movies.setMovieName(updateMovie.getMovieName());
                    Movies.setMovieDescription(updateMovie.getMovieDescription());
                    return moviesRepository.save(Movies);
                })
                .orElseGet(() -> {
                    updateMovie.setMovieId(id);
                    return moviesRepository.save(updateMovie);
                });
    }

    @CrossOrigin
    @PostMapping(path="/newMovie")
    public Movies addNewMovie (@RequestBody Movies data) {
       return moviesRepository.save(data);
    }


}

这是我的测试(更新)

package movieweb.movies;
import movieweb.movies.controllers.MoviesController;
import movieweb.movies.models.Movies;
import movieweb.movies.repository.MoviesRepository;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import org.testng.annotations.BeforeMethod;

import java.util.ArrayList;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.collection.IsCollectionWithSize.hasSize;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@SpringBootTest
@AutoConfigureMockMvc

class MovieApplicationTests {

    @Autowired
    MockMvc mockMvc;

    @MockBean
    MoviesRepository moviesRepository;

    @MockBean
    MoviesController moviesController;


    @Autowired
    private WebApplicationContext webApplicationContext;

    @BeforeMethod
    public void init() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();

    }

    @Test
    void getAllMovies() throws Exception{

        ArrayList<Movies> moviesList = new ArrayList<Movies>();
        moviesList.add(new Movies(1, "Star Wars", "A New Hope"));
        moviesList.add(new Movies(2, "Star Wars", "Empire Strikes Back"));

            when(moviesRepository.findAll()).thenReturn(moviesList);
        mockMvc.perform(get("/movies"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$", hasSize(2)))
                .andExpect(jsonPath("$[0].movieName", is("Star Wars")))
                .andExpect(jsonPath("$[0].movieDescription", is("A New Hope")))
                .andExpect(jsonPath("$[1].movieName", is("Star Wars")))
                .andExpect(jsonPath("$[1].movieDescription", is("Empire Strikes Back")));


        Mockito.verify(moviesRepository, times(1)).findAll();
    }
}

我在堆栈跟踪中遇到的错误如下......

java.lang.AssertionError: JSON path "$"
Expected: a collection with size <2>
     but: collection size was <0>

为什么它是零而不是我在 movieList ArrayList 中创建的 2 个项目?

我猜这与我的配置有关?

最佳答案

你正在 mock 你的 Controller :

@MockBean
MoviesController moviesController;

因此,您用此模拟替换了正在测试的真实 Controller 。 要拥有真正的 Controller ,您需要摆脱这些线。

要进一步改进,请了解 @WebMvcTest 以仅测试应用的 Web 切片。

关于java - MockMvc 和 Mockito - java.lang.AssertionError : JSON path "$" Expected: a collection with size <2> but: collection size was <0>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60689219/

相关文章:

Java : Reuse Bound Socket with different IP?

java - 使用 spring-boot 在库中设置默认属性

docker - 如何使JHipster应用程序REST服务在不同的Docker容器上运行?

使用 css 选择器解析 XML 的 Java 库

java - 解压缩时 FileOutputStream 抛出 FileNotFoundException

spring-boot - 如何在一个 MVC 应用程序中结合 @DataJpaTest @SpringBootTest 来测试每一层?

spring-boot - 无法使用 Spring Boot Test 测试自定义存储库

java - Spring Boot 入门项目 - 错误解决模板

java - 从文件加载大 HashMap<String, TreeMap> 会给出 java.lang.OutOfMemoryError(超出 GC 开销限制)

spring-boot - 如何让 Spring Boot Kotlin bootRun 和 devtools 重启得更快?