gpt4 book ai didi

java - 如何使用 Mockito 模拟包含 EntityManager

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:47:24 25 4
gpt4 key购买 nike

目前在学校我们正在做一个相当大的项目。然而,Java 中的测试并没有得到很好的解释,所以我并没有像我想象的那样真正地使用 TDD。

protected EntityManager getEntityManager() {
return EntityController.getEntityManager();
}

// Get all exam skeletons from the DB
@Override
public List<ExamSkeleton> getAllSkeletons() {
EntityManager entityManager = getEntityManager();
try {
TypedQuery<ExamSkeleton> query = entityManager.createQuery("SELECT NEW ExamSkeleton (s.id, s.filename, s.course, s.visible) FROM ExamSkeleton as s", ExamSkeleton.class);

List<ExamSkeleton> skeletons = query.getResultList();

return skeletons;
} catch (IllegalArgumentException exception) {
LOGGER.error(exception);
}
return Collections.emptyList();
}

所以我的问题是,如何使用 Mockito 测试此方法?

最佳答案

方法 1:测试代码原样

getEntityManager 方法是私有(private)的,它会调用静态方法,因此,就目前情况而言,您需要使用 PowerMockito 在测试中提供 EntityManager 的模拟实例.例如:

@RunWith(PowerMockRunner.class)
@PrepareForTest({EntityController.class})
public class SomeTest {

@Test
public void aTest() {
PowerMockito.mockStatic(EntityController.class);

EntityManager entityManager = Mockito.mock(EntityManager.class);
Mockito.when(EntityController.getEntityManager()).thenReturn(entityManager);

TypedQuery<ExamSkeleton> query = (TypedQuery<ExamSkeleton>) Mockito.mock(TypedQuery.class);

Mockito.when(entityManager.createQuery("SELECT NEW ExamSkeleton (s.id, s.filename, s.course, s.visible) FROM ExamSkeleton as s")).thenReturn(query);

List<ExamSkeleton> expected = new ArrayList<>();
Mockito.when(query.getResultList()).thenReturn(expected);

ExamRepository examRepository = new ExamRepository();

List<ExamSkeletons> actual = examRepository.getAllSkeletons();

// this assertion verifies that getAllSkeletons gives you the result of the above SQl query
assertSame(expected, actual);
}
}

方法 2:重构以分离关注点并简化测试

但是,您可以从测试和设计的角度简化事情,例如,通过将实体管理器的创建外部化到工厂中。

public class EntityManagerFactory {

public EntityManager create() {
return EntityController.getEntityManager();
}
}

接下来,将 EntityManagerFactory 的实例注入(inject)到任何包含 getAllSkeletons() 的类(即您正在测试的类)中。最简单的方法是将其声明为构造函数参数:

public class SomeDao {
private final EntityManagerFactory entityManagerFactory;

public SomeDao(EntityManagerFactory entityManagerFactory) {
this.entityManagerFactory = entityManagerFactory;
}

@Override
public List<ExamSkeleton> getAllSkeletons() {
try {
TypedQuery<ExamSkeleton> query = entityManager.createQuery("SELECT NEW ExamSkeleton (s.id, s.filename, s.course, s.visible) FROM ExamSkeleton as s", ExamSkeleton.class);

List<ExamSkeleton> skeletons = query.getResultList();

return skeletons;
} catch (IllegalArgumentException exception) {
LOGGER.error(exception);
}
return Collections.emptyList();
}
}

现在,您可以使用 vanilla mockito 测试此代码。例如:

public class SomeDaoTest {

@Test
public void canGetAllSkeletons() {
EntityManagerFactory entityManagerFactory = Mockito.mock(EntityManagerFactory.class);

Mockito.when(entityManagerFactory.create()).thenReturn(entityManager);

SomeDao sut = new SomeDao(entityManagerFactory.class);

// now SomeDao will use your mocked EntityManager so you can set expectations
// on createQuery etc to drive your test scenarios
// ...
}
}

关于java - 如何使用 Mockito 模拟包含 EntityManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50528520/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com