AuditingEntityListener junit找不到上下文

时间:2019-02-27 18:42:17

标签: java spring hibernate jpa spring-data-jpa

我有一个实体,想实现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);
    }
}

2 个答案:

答案 0 :(得分:1)

问题是,您不是在使用spring的AOP,而是在静态上下文中使用

private static ApplicationContext context;

它为空,因为不创建@Bean会导致未代理的对象。解决方案是@Autowire

答案 1 :(得分:1)

这就是我在测试课程中解决问题的方式

@自动连线 ApplicationContext上下文;

在称为

的测试方法中
BeanUtil beanUtil = new BeanUtil();
beanUtil.setApplicationContext(context);

它奏效了。