Java EE中的Junit测试(JPA)

时间:2022-05-06 20:36:03

I'm creating a simple web application in JAVA EE using (EJB, JPA and JPQL). I want to know how to test the model using mockito to test the EJB. I want to mock the context (database, and properties)

我正在使用(EJB,JPA和JPQL)在JAVA EE中创建一个简单的Web应用程序。我想知道如何使用mockito测试模型来测试EJB。我想模拟上下文(数据库和属性)

How do I do that ?

我怎么做 ?

@Mock
private EntityManager mockedEntityManager;
private static TendererBean tendererBean;
private static TendererManagerBean tendererManagerBean;   
private static EJBContainer container;
final Properties p = new Properties();
    p.put("jdbc/Mydatabase", "new://Resource?type=DataSource");
    p.put("jdbc/Mydatabase.JdbcDriver", "apache_derby_net");
    p.put("jdbc/Mydatabase.JdbcUrl", "jdbc:derby://localhost:1527/Mydatabase");
    container = EJBContainer.createEJBContainer(p);
    final Context context = container.getContext();
    tendererBean = (TendererBean) context.lookup("java:global/classesTendererManagerBean");

2 个解决方案

#1


2  

Alex is right, you should not need database connections in a unit test (unless you trying to create an integration test) You can try mocking them like this. The code may be messy, hope it helps

Alex是对的,您不应该在单元测试中需要数据库连接(除非您尝试创建集成测试)您可以尝试像这样模拟它们。代码可能很乱,希望它有所帮助

public class ChargeServiceTest {

@InjectMocks
private ChargeService chargeService;

@Mock
private EntityManager entityManager;

@Mock
private Query query;
@Mock
private Biller biller;
@Mock
private Client client;

private String expectedSqlQuery1 = "Select count(c) from ClientContractCharge c where c.clientContract.biller =?1 and c.recurringInvoice = true and c.clientContract.client = ?2 and (c.dateCreated >= ?3 or c.dateLastUpdated >= ?3)  order by c.dateCreated ASC";

@Before
public void before() {
    chargeService = new ChargeService();
    MockitoAnnotations.initMocks(this);
}

@Test
public void listCountTest1() {
    when(entityManager.createQuery(expectedSqlQuery1)).thenReturn(query);
    when(query.getSingleResult()).thenReturn((long) 10);
    Long count = chargeService.listCount(biller, client);
    verify(query).setParameter(1, biller);
    assertEquals(count, Long.valueOf(10));
}
}

Service class

服务类

@Stateless
@LocalBean public class ChargeService {
public long listCount(Biller biller, Client client) {

    StringBuilder s = new StringBuilder();
    s.append("Select count(c) from ClientContractCharge c where c.clientContract.biller =?1 and c.recurringInvoice = true ");
    if (client != null) {
        s.append("and c.clientContract.client = ?2 ");
    }
    s.append(" order by c.dateCreated ASC");
    Query q = em.createQuery(s.toString());
    q.setParameter(1, biller);
    if (client != null) {
        q.setParameter(2, client);
    }

    return (long) (Long) q.getSingleResult();
}

#2


1  

It should not be necessary to hassle around with db properties in your test code. Another thing to keep in mind: A unit test should not need a database connection, because then it's more than a unit test, it should mock away the persistence.

没有必要在测试代码中使用db属性。另外要记住的是:单元测试不需要数据库连接,因为它不仅仅是一个单元测试,它应该模拟持久性。

EntityManager can easily be mocked with for example Mockito. Additionally, you can mock a Query to get the needed result for the test.

可以使用例如Mockito轻松模拟EntityManager。此外,您可以模拟查询以获得测试所需的结果。

Check out Adam Bien's post on Mocking JPA EntityManager and Query for how this can be done.

查看Adam Bien关于Mocking JPA EntityManager和Query的帖子,了解如何做到这一点。

#1


2  

Alex is right, you should not need database connections in a unit test (unless you trying to create an integration test) You can try mocking them like this. The code may be messy, hope it helps

Alex是对的,您不应该在单元测试中需要数据库连接(除非您尝试创建集成测试)您可以尝试像这样模拟它们。代码可能很乱,希望它有所帮助

public class ChargeServiceTest {

@InjectMocks
private ChargeService chargeService;

@Mock
private EntityManager entityManager;

@Mock
private Query query;
@Mock
private Biller biller;
@Mock
private Client client;

private String expectedSqlQuery1 = "Select count(c) from ClientContractCharge c where c.clientContract.biller =?1 and c.recurringInvoice = true and c.clientContract.client = ?2 and (c.dateCreated >= ?3 or c.dateLastUpdated >= ?3)  order by c.dateCreated ASC";

@Before
public void before() {
    chargeService = new ChargeService();
    MockitoAnnotations.initMocks(this);
}

@Test
public void listCountTest1() {
    when(entityManager.createQuery(expectedSqlQuery1)).thenReturn(query);
    when(query.getSingleResult()).thenReturn((long) 10);
    Long count = chargeService.listCount(biller, client);
    verify(query).setParameter(1, biller);
    assertEquals(count, Long.valueOf(10));
}
}

Service class

服务类

@Stateless
@LocalBean public class ChargeService {
public long listCount(Biller biller, Client client) {

    StringBuilder s = new StringBuilder();
    s.append("Select count(c) from ClientContractCharge c where c.clientContract.biller =?1 and c.recurringInvoice = true ");
    if (client != null) {
        s.append("and c.clientContract.client = ?2 ");
    }
    s.append(" order by c.dateCreated ASC");
    Query q = em.createQuery(s.toString());
    q.setParameter(1, biller);
    if (client != null) {
        q.setParameter(2, client);
    }

    return (long) (Long) q.getSingleResult();
}

#2


1  

It should not be necessary to hassle around with db properties in your test code. Another thing to keep in mind: A unit test should not need a database connection, because then it's more than a unit test, it should mock away the persistence.

没有必要在测试代码中使用db属性。另外要记住的是:单元测试不需要数据库连接,因为它不仅仅是一个单元测试,它应该模拟持久性。

EntityManager can easily be mocked with for example Mockito. Additionally, you can mock a Query to get the needed result for the test.

可以使用例如Mockito轻松模拟EntityManager。此外,您可以模拟查询以获得测试所需的结果。

Check out Adam Bien's post on Mocking JPA EntityManager and Query for how this can be done.

查看Adam Bien关于Mocking JPA EntityManager和Query的帖子,了解如何做到这一点。