2016-11-22 101 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'。 –