首页 > 解决方案 > Springboot 测试与 commandLineRunner 给出不同的结果

问题描述

这是 MVCE:https ://github.com/neo4j-examples/movies-java-spring-data-neo4j

我添加到 Person 实体方法:

public void addMovie(Movie movie) {
    if (this.movies == null) {
        this.movies = new ArrayList<>();
    }
    this.movies.add(movie);
}

测试中我添加了:在设置中:

    keanu.addMovie(matrix);
    personRepository.save(keanu);

在其中一项测试中:

Person p = personRepository.findByName("Keanu Reeves");

在调试模式下,我清楚地看到 p 在获取时具有电影集合。

从 github 测试更改代码后,它看起来像这样:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Transactional
public class MovieRepositoryTest {
    @Autowired
    private MovieRepository movieRepository;

    @Autowired
    private PersonRepository personRepository;

    @Before
    public void setUp() {
        Movie matrix = new Movie("The Matrix", 1999, "Welcome to the Real World");

        movieRepository.save(matrix);
        Person keanu = new Person("Keanu Reeves", 1964);
        personRepository.save(keanu);
        Role neo = new Role(matrix, keanu);
        neo.addRoleName("Neo");
        matrix.addRole(neo);
        keanu.addMovie(matrix);
        personRepository.save(keanu);
        movieRepository.save(matrix);
    }

    /**
     * Test of findByTitle method, of class MovieRepository.
     */
    @Test
    public void testFindByTitle() {

        String title = "The Matrix";
        Movie result = movieRepository.findByTitle(title);
        Person p = personRepository.findByName("Keanu Reeves");

        assertNotNull(result);
        assertEquals(1999, result.getReleased());
    }

    /**
     * Test of findByTitleContaining method, of class MovieRepository.
     */
    @Test
    public void testFindByTitleContaining() {
        String title = "*Matrix*";
        Collection<Movie> result = movieRepository.findByTitleLike(title);
        assertNotNull(result);
        assertEquals(1, result.size());
    }

    /**
     * Test of graph method, of class MovieRepository.
     */
    @Test
    public void testGraph() {
        Collection<Movie> graph = movieRepository.graph(5);

        assertEquals(1, graph.size());

        Movie movie = graph.iterator().next();

        assertEquals(1, movie.getRoles().size());

        assertEquals("The Matrix", movie.getTitle());
        assertEquals("Keanu Reeves", movie.getRoles().iterator().next().getPerson().getName());
    }
}

但如果我这样做:

  @Bean
    CommandLineRunner demo(PersonRepository personRepository, MovieRepository movieRepository) {
        return args -> {
        personRepository.deleteAll();
        movieRepository.deleteAll();

        Movie matrix = new Movie("The Matrix", 1999, "Welcome to the Real World");

        movieRepository.save(matrix);

        Person keanu = new Person("Keanu Reeves", 1964);

        personRepository.save(keanu);

        Role neo = new Role(matrix, keanu);
        neo.addRoleName("Neo");

        matrix.addRole(neo);

        keanu.addMovie(matrix);
        personRepository.save(keanu);

        movieRepository.save(matrix);


        Movie result = movieRepository.findByTitle("The Matrix");
        Person p = personRepository.findByName("Keanu Reeves");
    };
}

我看到 p 没有任何电影。为什么有区别?代码与测试中的相同。

标签: javahibernatespring-bootneo4j

解决方案


我对 neo4j 不熟悉,但是我猜想这是因为测试在 a 中运行,@Transaction而命令行运行程序执行的代码却没有。

因此,将命令行运行器中的逻辑删除到可以包装在事务中的某个位置,无论是服务类还是应用程序侦听器。


推荐阅读