繁体   English   中英

Spring启动测试:测试通过,但不应该(误报)

[英]Spring boot test: Test passes, but should not (false positive)

我有测试的Spring Boot项目没有失败(但应该)。

我做错了什么或者是Spring的问题?

对于一个小例子,我创建了一个包含2个实体(User和Category)的小项目和一个具有DELETE方法的Controller类( https://github.com/sk8ter/demo )。

类别实体的ID为User实体,没有级联选项,因此在删除具有类别的用户时应该失败:

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue
    private long id;
    private String name;
    ...
}

@Entity
@Table(name = "category")
public class Category {

    @Id
    @GeneratedValue
    private long id;
    private String name;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false)
    private User user;
    ...
}

控制器也很简单:

@RestController
@RequestMapping(value = "/users", produces = "application/json;charset=UTF-8")
public class UserCategory {

    @Autowired
    private UserRepository userRepository;

    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{id}", method = DELETE, consumes =   MediaType.ALL_VALUE)
    public void deleteCategory(@PathVariable Long id) {
        User user = userRepository.getOne(id);
        userRepository.delete(user);
    }
}

最后一个测试:

@Transactional
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = DemoApplication.class)
public class DemoApplicationTests {

    @Autowired
    protected WebApplicationContext context;

    protected MockMvc mockMvc;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    @Test
    public void testName() throws Exception {
        mockMvc.perform(delete("/users/1"))
                .andExpect(status().isOk());

//      EntityManagerFactory entityManagerFactory = context.getBean(EntityManagerFactory.class);
//      SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
//      sessionFactory.getCurrentSession().flush();
    }
}

如果我从DemoApplicationTests中删除@Transactional注释,测试将失败,但在这种情况下,更改将提交给DB。

测试中评论的3行也没有帮助。

我不想用@Rollback(false)注释方法或类,因为我希望我的所有测试都是幂等的 如果我注释@Rollback(false) ,H2也会因外键的约束而失败。

我找到了解决方案:

@Transactional
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = DemoApplication.class)
public class DemoApplicationTests {

    @Autowired
    protected WebApplicationContext context;

    protected MockMvc mockMvc;

    @PersistenceContext
    EntityManager em;

    @Before
    public void setUp() {
        mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build();
    }

    @Test
    public void testName() throws Exception {
        mockMvc.perform(delete("/users/1"))
                .andExpect(status().isOk());

        em.flush();
    }
}

关键线:

@PersistenceContext
EntityManager em;
...
// Manual flush is required to avoid false positive in test
em.flush();

所以SessionFactory在Spring Documentation中不起作用

// Manual flush is required to avoid false positive in test
sessionFactory.getCurrentSession().flush();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM