我试图为使用JPA作为DAO层的Create(Post)方法编写单元测试。我是莫皮托的新手,因此需要见解。
1.EmployeeService .java
@Component("IEmployeeService ")
public class EmployeeService implements IInputService {
@Inject
EntityManagerFactory emf;
@PersistenceContext
EntityManager em;
public InputEntity create(InputEntity inputEntity) {
em = emf.createEntityManager();
try {
em.getTransaction().begin();
inputEntity.setLST_UPDTD_TS(new Date());
inputEntity.setLST_UPDTD_USER_ID(new String("USER1"));
em.persist(inputEntity);
em.getTransaction().commit();
} catch (PersistenceException e)
{
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
throw new WebApplicationException(e,Response.Status.INTERNAL_SERVER_ERROR);
}
finally {
em.close();
}
return inputEntity;
}
2.输入实体.java是实体类,具有与员工年龄,薪水等对应的列的getter和setter。
现在,如果调用 Post 方法,将调用 EmployeeService 类中的创建方法。我必须使用 mockito 编写一个单元测试,并且我得到空指针,下面是我编写的测试。
@Category(UnitTest.class)
@RunWith(MockitoJUnitRunner.class)
public class EmployeeServiceTest {
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
@Autowired
EmployeeService employeeService;
@Mock
InputEntity inputEntity;
@Mock
EntityManagerFactory emf;
@Mock
private EntityManager em;
@Mock
private EntityTransaction et;
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void test_create_employee_success() throws Exception {
InputEntity expected = Mockito.mock(InputEntity .class);
Mockito.when(em.getTransaction()).thenReturn(et);
Mockito.when(emf.createEntityManager()).thenReturn(em);
Mockito.doReturn(expected).when(employeeService).create(inputEntityMock);
InputEntity actual = new InputEntity();
Mockito.doReturn(actual).when(employeeService).create(inputFileRoleValidationMock);
assertEquals(expected, actual);
}
你有一个本地模拟expected
,你试图在assertEquals()中使用,但这永远不会起作用,因为assertEquals使用Object.equals
,而Mockito劫持equals
供内部使用。 Mockito模拟永远不会Object.equals
任何东西,除了它自己。
我们遇到了类似的NullPointerException问题,这是因为实体管理器。在 setUp 方法中更新连接属性后,我们可以调用 JPA。
您可以尝试设置这样的连接属性。
//declare emfactory
private static EntityManagerFactory emfactory;
private static EntityManager em;
@BeforeClass
public static void setUp() throws Exception{
Map<Object, Object> properties = new HashMap<Object, Object>();
properties.put("openjpa.ConnectionURL",
"jdbc:db2://yourserver:port/DBName");
properties.put("openjpa.ConnectionUserName", "username");
properties.put("openjpa.ConnectionPassword", "userpassword");
//set Schema
//set Driver Name
emfactory = Persistence.createEntityManagerFactory("PersistenceUnitName",
properties);
em = emfactory.createEntityManager();
Mockito.when(emf.createEntityManager()).thenReturn(em);
}
另外,您需要修改test_create_employee_success()才能使其正常工作。你正在嘲笑这种方法中的所有东西,这是你不应该做的。你可以试试这样的事情。
@Test
public void test_create_employee_success() throws Exception {
{
InputEntity inputEntity = new InputEntity();
employeeService.create(inputEntity);
}
您需要对代码进行以下更改:
1.代替
@Autowired
EmployeeService employeeService;
您可以使用:
@InjectMocks
private EmployeeService EmployeeService;
同样当你在方法中模拟时 - InputEntity expected = Mockito.mock(InputEntity .class); 除非在其他一些方法中使用,否则在类级别不需要此声明。
你也可以摆脱声明——
InputEntityactual = new InputEntity();
不能断言模拟对象和使用 new 关键字表示相等的对象。
干净的单元测试将如下所示-
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class EmployeeServiceImplTest {
@Mock
private EntityManager em;
@Mock
private EntityManagerFactory emf;
@InjectMocks
private EmployeeService EmployeeService;
@Mock
private EntityTransaction et;
@Test
public void testCreate() throws Exception {
InputEntity expected = Mockito.mock(InputEntity.class);
Mockito.when(em.getTransaction()).thenReturn(et);
Mockito.when(emf.createEntityManager()).thenReturn(em);
EmployeeService.create(expected);
Mockito.verify(em, Mockito.times(1)).persist(expected);
}
}