[英]How to test generic abstract class with @Autowired fields?
I have generic abstract class AbstractBaseEntityGenericDao which contains @Autowired field.我有包含@Autowired 字段的通用抽象类 AbstractBaseEntityGenericDao。 It worked perfectly until I had to write a unit test for it, to not duplicate the same code inside all tests for classes which extends it.它工作得很好,直到我不得不为它编写单元测试,不要在扩展它的类的所有测试中复制相同的代码。 And now I'm thinking...Is it possible to write a unit/integration test for such class?现在我在想……是否可以为此类课程编写单元/集成测试?
@Repository
@Transactional
public abstract class AbstractBaseEntityGenericDao<T extends BaseEntity> {
private Class<T> classInstance;
private SessionFactory sessionFactory;
@Autowired
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public final void setClassInstance(Class<T> clasInstance) {
this.classInstance = clasInstance;
}
public void create(@NonNull T entity) {
Session session = sessionFactory.getCurrentSession();
session.save(entity);
}
public Optional<T> find(long id) {
Session session = sessionFactory.getCurrentSession();
return Optional.ofNullable(session.get(classInstance, id));
}
public void update(@NonNull T entity) {
Session session = sessionFactory.getCurrentSession();
session.saveOrUpdate(entity);
}
public void remove(@NonNull Long id) throws EntityNotFoundException {
Session session = sessionFactory.getCurrentSession();
session.remove(session.load(classInstance, id));
}
public void remove(@NonNull T entity) {
Session session = sessionFactory.getCurrentSession();
session.remove(entity);
}
}
The reason this is difficult is because generally you should not be doing this.这很困难的原因是因为通常你不应该这样做。 The abstract class should have no knowledge of how its child creates SessionFactory
.抽象类应该不知道它的子类如何创建SessionFactory
。 so instead it should look something like:所以它应该看起来像:
@Repository
@Transactional
public abstract class AbstractBaseEntityGenericDao<T extends BaseEntity> {
...
protected SessionFactory sessionFactory;
...
}
Now you CANNOT directly unit test a abstract class as it can not be instantiated.现在你不能直接对抽象类进行单元测试,因为它不能被实例化。 you can however stub it out in a unit test, and test that stub.但是,您可以在单元测试中将其存根,然后测试该存根。 The stub in turn will have a constructor for the protected field which we can mock out in the unit test.存根反过来将有一个受保护字段的构造函数,我们可以在单元测试中模拟它。 In the end it would look like:最后它看起来像:
public class AbstractBaseEntityGenericDaoTest {
private class AbstractClassStub extends AbstractBaseEntityGenericDao {
public AbstractClassStub(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public void create(BaseEntity entity) {
super.create(entity);
}
@Override
public Optional find(long id) {
return super.find(id);
}
@Override
public void update(BaseEntity entity) {
super.update(entity);
}
@Override
public void remove(@NonNull Long id) throws EntityNotFoundException {
super.remove(id);
}
@Override
public void remove(BaseEntity entity) {
super.remove(entity);
}
}
@Mock
SessionFactory sessionFactory;
private AbstractClassStub abstractClassStub;
@Before
public void before() {
sessionFactory = mock(SessionFactory.class);
abstractClassStub = new AbstractClassStub(sessionFactory);
}
@Test
public void testWhatever() {
abstractClassStub.find(1); //or whatever
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.