ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-Spring Boot测试:测试通过,但不应通过(假肯定)

2019-11-19 11:29:14  阅读:197  来源: 互联网

标签:spring-boot testing spring-mvc-test spring java


我有带有测试的Spring Boot项目,它不会失败(但应该).

我是在做错什么,还是Spring的问题?

作为一个小示例,我创建了一个小项目,其中包含2个实体(用户和类别)和一个具有DELETE方法(https://github.com/sk8ter/demo)的Controller类.

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

@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批注,则测试将失败,但是在这种情况下,更改将提交给数据库.

测试中注释3行也无济于事.

解决方法:

我不想使用@Rollback(false)注释方法或类,因为我希望所有测试都为idempotent.如果我注释@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();

标签:spring-boot,testing,spring-mvc-test,spring,java
来源: https://codeday.me/bug/20191119/2035788.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有