我使用SpringBoot1.4.0.M3。
我有一个@Entity,它的username应该是唯一的:
@NotNull
@Column(unique = true)
@Pattern(regexp = "[a-zA-Z_\\-\\.0-9]+")
@Size(min = 1, max = 30)
private String username;使用,我想测试在使用重复用户名时是否会出现异常。此测试工作:
@SpringBootTest
@RunWith(SpringRunner.class)
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository repository;
@Test(expected = DataIntegrityViolationException.class)
public void test() {
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
}
}但是,当使用@Transactional添加@Commit时,此测试失败:
@SpringBootTest
@RunWith(SpringRunner.class)
@Transactional
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository repository;
@Test(expected = DataIntegrityViolationException.class)
@Commit
public void test() {
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
}
}但是,看看日志记录,就会抛出DataIntegrityViolationException:
2016-05-24 09:05:16.619错误22790 -主o.h.engine.jdbc.spi.SqlExceptionHelper :唯一索引或主键违规:"UK_D8HGQ87BS4VPMC81NQ9G69G8X_INDEX_D ON PUBLIC.MYPROJECT_USER(用户名)值('wim',1)";SQL语句:插入myproject_user值(密码、用户名、角色、id)值(?、?、'ADMIN‘、?) 23505-191 2016-05-24 09:05:16.620 INFO 22790 main o.h.e.j.b.internal.AbstractBatchImpl : HHH000010:在批处理发布时,仍然包含JDBC语句2016-05-24 09:05:16.629警告22790 --主o.s.test.context.TestContextManager :捕获异常,同时允许org.springframework.test.context.transaction.TransactionalTestExecutionListener@589b3632为测试执行“后”处理:方法公开无效com.spring.boot.test.user.UserRepositoryIntegrationTest.test(),实例com.spring.boot.test.user.UserRepositoryIntegrationTest@3ca278bc,异常java.lang.AssertionError:预期异常: org.springframework.dao.DataIntegrityViolationException
为什么考试不及格?JUnit会检查在Spring提交事务之前是否抛出异常吗?
发布于 2016-05-24 12:59:18
你不需要承诺。您只需要将您的工作单元刷新到数据库中,就可以看到DataIntegrityViolationException。
这在弹簧参考手册中关于“假阳性”的说明中有描述。但是,请注意,EntityManager必须通过@PersistenceContext (而不是@Autowired)注入。
以下几点对你来说应该很好:
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class UserRepositoryIntegrationTest {
@Autowired
UserRepository repository;
@PersistenceContext
EntityManager entityManager;
@Test(expected = DataIntegrityViolationException.class)
public void test() {
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
entityManager.flush();
}
}致以敬意,
Sam ( Spring TestContext框架的作者)
发布于 2016-05-24 07:20:13
根据M.Deinum和Stephane的评论,以下是工作版本:
@SpringBootTest
@RunWith(SpringRunner.class)
@Transactional
public class UserRepositoryIntegrationTest {
@Autowired
private UserRepository repository;
@Test(expected = DataIntegrityViolationException.class)
public void test() {
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
repository.save(User.createAdmin(repository.nextId(), "wim", "123456"));
TestTransaction.flagForCommit();
TestTransaction.end();
}
}请注意,需要调用这两个静态方法才能使其工作。
发布于 2017-02-19 22:58:57
我需要在MVC控制器测试(@WebAppConfiguration)中测试@WebAppConfiguration,并通过@ControllerAdvice.So在应用程序中进行@ResponseStatus修改--您的方法不适合我,太晚了。不幸的是,@NotTransactional注释在Spring 4中被排除在外,所以我只是将@Transactional测试与非事务性测试分开。也请参阅http://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/testing.html#integration-testing-annotations
@NotTransactional被弃用
最新消息。2种解决办法:
@Transactional(propagation = Propagation.NEVER)https://stackoverflow.com/questions/37406714
复制相似问题