2016-11-22 121 views
0

我使用:Netbeans的,Glassfish的,的Mockito嘲讽的EntityManager而EJB类的测试

虽然与Java EE工作的我第一次来试图测试使用的数据库进行交互方式跨越问题EntityManager的。

在下面的代码片段中,我试图模拟出实体管理器,所以我知道数据库交互不会被完全测试,并且对于这个测试来说也没关系。但我正在努力实现UsersController,因为它注入了EntityManager,总是null。我想EntityManager被嘲笑,所以我可以测试其余的方法。

下面是一个与db交互的类。注意这是一个示例方法,它不适用于生产。

@Stateless 
public class UsersController { 
    @PersistenceContext() 
    EntityManager em; 

    public User getOne() { 
     em.getEntityManagerFactory().getCache().evictAll(); 
     User theUser = null; 
     try { 
      Query q = em.createNamedQuery("User.findAll"); 
      Collection<User> entities = q.getResultList(); 
      theUser = Iterables.get(entities, 1); 
     } 
     catch(NoResultException e){} 
     em.flush(); 
     return theUser; 
    }; 
} 

将测试此方法的测试文件。

@RunWith(MockitoJUnitRunner.class) 
public class UsersControllerTest { 

    @Mock 
    private UsersController usersController; 
    @Mock 
    private EntityManager entityManagerMock; 

    private Collection<User> mockUsersDbCollection = //... 

    @BeforeClass 
    public void setUpClass() { 

     when(entityManagerMock.createNamedQuery("User.findAll")).thenReturn(mockUsersDbCollection); 
    } 

    @Test 
    public void findOneTest(){ 
     User mockUserDbEntry = new User("1", "pa$$word", "salt", "user1", "[email protected]", false); 

     User returnedUser = null; 
     returnedUser = usersController.getOne(); 

     assertEquals(returnedUser.getId(), "1"); 
    } 
} 

每当UsersController模拟创建的EntityManager总是空造成的问题,我怎么能注入EntityManagerMock所以它是否行得通呢?

回答

0

你有几个问题在这里:

  • 您测试UsersController,因此它不应该被嘲笑;而因为你要到的Mockito注入你的模拟实体管理器,你应该使用它的@InjectMocks注释

  • @BeforeClass注释只有当适用于静态方法,而这又只能访问静态实例变量的作品;在这种情况下,我认为你只需要@Before注释

  • entityManagerMock.createNamedQuery需要返回一个模拟Query对象,你粘贴代码甚至不应该编译

最后,您的测试看起来应该如:

@RunWith(MockitoJUnitRunner.class) 
public class UsersControllerTest { 

    @InjectMocks 
    private UsersController usersController; 

    @Mock 
    private EntityManager entityManagerMock; 

    @Mock 
    private EntityManagerFactory entityManagerFactory; 

    @Mock 
    private Cache emfCache; 

    @Mock 
    private Query findAllQuery; 

    private List<User> mockUsersDbCollection = //... 

    @Before 
    public void setUp() { 
     when(entityManagerFactory.getCache()) 
      .thenReturn(emfCache); 
     when(entityManagerMock.getEntityManagerFactory()) 
      .thenReturn(entityManagerFactory); 
     when(entityManagerMock.createNamedQuery("User.findAll")) 
      .thenReturn(findAllQuery); 
     when(findAllQuery.getResultList()) 
      .thenReturn(mockUsersDbCollection); 
    } 

    @Test 
    public void findOneTest(){ 
     mockUsersDbCollection.add(new User("1", "pa$$word", "salt", "user1", "[email protected]", false)); 

     User returnedUser = usersController.getOne(); 

     assertEquals(returnedUser.getId(), "1"); 
    } 
} 
+0

感谢您的反馈,但我仍然有问题。调用em.getEntityManagerFactory()。getCache()。evictAll();时我有一个空指针异常,但我认为entityManager被嘲笑了? –

+0

是的 - 错过了那条线。请记住,所有模拟的默认行为是什么都不做,并在适当的地方返回'null'或'0'。 –