这是关于
TestExecutionListener回调和
@Before测试方法的计时问题。
@WithUserDetails由Spring
Security的支持
WithSecurityContextTestExecutionListener,这将永远不会运行 后
一个
@Before方法。因此,Spring
Security不可能看到您在您的
setUp()方法中坚持使用数据库的用户。基本上这就是异常告诉您的内容:Spring
Security尝试从数据库中读取用户,然后再将其存在。
解决此问题的一种方法是迁移以
@Sql支持在数据库中插入测试数据。您可能不会发现像持久保存实体那样 舒适 , 但是
这种
@Sql方法允许在测试管理的事务中创建测试数据(即不需要手动清理)。请注意,您必须升级到Spring Security 4.1.1才能正常工作。
解决此问题的另一种方法是
@BeforeTransaction使用一种方法(例如,使用Spring的方法)将实体保留在用户管理的事务中
TransactionTemplate。但是,您随后将需要以
@AfterTransaction类似方式手动清理数据库。另外,您仍然需要升级到Spring
Security 4.1.1才能使它起作用。
如下所示的方法可以解决问题:
@Autowiredprivate TestEntityManager testEntityManager;@AutowiredPlatformTransactionManager transactionManager;@BeforeTransactionpublic void setUp() { new TransactionTemplate(transactionManager).execute(status -> { UserAccount owner = testEntityManager.persist(createUserAccount(OWNER_OF_ADVERTISEMENT_EMAIL)); Language language = testEntityManager.persist(createLanguage("Français")); DayToTimeSlot dayToTimeSlot = testEntityManager.persist(createDayToTimeSlot()); advertisement = testEntityManager.persist(createAdvertisement(owner, language, dayToTimeSlot)); impersonator = testEntityManager.persist(createUserAccount(IMPERSONATOR_EMAIL)); return null; });}@AfterTransactionpublic void tearDown() { new TransactionTemplate(transactionManager).execute(status -> { testEntityManager.remove(testEntityManager.find(Advertisement.class, advertisement.getId())); UserAccount owner = advertisement.getUserAccount(); testEntityManager.remove(testEntityManager.find(UserAccount.class, owner.getId())); testEntityManager.remove(testEntityManager.find(UserAccount.class, impersonator.getId())); return null; });}问候,
山姆



