我有一个实体,想实现Audit和AuditHistory,两者都可以,但是在单元测试中Application上下文为空。
实体
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(UserListener.class)
public class User extends BaseModel<String> {
@Column
private String username;
@Column
private String password;
@Transient
private String passwordConfirm;
@ManyToMany
private Set<Role> roles;
}
UserListener
public class UserListener {
@PrePersist
public void prePersist(User target) {
perform(target, INSERTED);
}
@PreUpdate
public void preUpdate(User target) {
perform(target, UPDATED);
}
@PreRemove
public void preRemove(User target) {
perform(target, DELETED);
}
@Transactional(MANDATORY)
void perform(User target, Action action) {
EntityManager entityManager = BeanUtil.getBean(EntityManager.class);
if(target.isActive()){
entityManager.persist(new UserAuditHistory(target, action));
}else{
entityManager.persist(new UserAuditHistory(target, DELETED));
}
}
}
UserAuditHistory
@Entity
@EntityListeners(AuditingEntityListener.class)
public class UserAuditHistory {
@Id
@GeneratedValue
private Long id;
@ManyToOne
@JoinColumn(name = "user_id", foreignKey = @ForeignKey(name = "FK_user_history"))
private User user;
@CreatedBy
private String modifiedBy;
@CreatedDate
@Temporal(TIMESTAMP)
private Date modifiedDate;
@Enumerated(STRING)
private Action action;
public UserAuditHistory() {
}
public UserAuditHistory(User user, Action action) {
this.user = user;
this.action = action;
}
}
BeanUtil用于获取和设置上下文
@Service
public class BeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> beanClass) {
return context.getBean(beanClass);
}
}
现在在Junit中,从上述getBean()方法中的BeanUtil类的上下文中获取空指针异常。
@RunWith(SpringRunner.class)
@DataJpaTest
public class UserRepositoryTest{
@Autowired
private TestEntityManager entityManager;
@Autowired
private UserRepository repository;
@Test
public void whenFindAll_theReturnListSize(){
entityManager.persist(new User("jk", "password", "password2", null));
assertEquals(repository.findAll().size(), 1);
}
}
答案 0 :(得分:1)
问题是,您不是在使用spring的AOP,而是在静态上下文中使用
private static ApplicationContext context;
它为空,因为不创建@Bean
会导致未代理的对象。解决方案是@Autowire
。
答案 1 :(得分:1)
这就是我在测试课程中解决问题的方式
@自动连线 ApplicationContext上下文;
在称为
的测试方法中BeanUtil beanUtil = new BeanUtil();
beanUtil.setApplicationContext(context);
它奏效了。