NullPointerException при использовании Mockito - PullRequest
0 голосов
/ 16 декабря 2011

Я пытаюсь создать тест с использованием Mockito, однако получаю исключение NullPointerException.

Ниже приводится сессионный компонент:

package edu.city.set.eia.citypress.beans;

import edu.city.set.eia.citypress.model.RegisUser;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;


@Stateless
public class RegisUserFacade extends AbstractFacade<RegisUser> implements RegisUserFacadeLocal {
    @PersistenceContext(unitName = "citypress_PU")
    private EntityManager em;

    @Override
    public EntityManager getEntityManager() {
        return em;
    }

    public void setEntityManager(EntityManager em) {
        this.em = em;
    }


    public RegisUserFacade() {
        super(RegisUser.class);
    }


    @Override
    public RegisUser findByUsername(String username) {
        Query query = this.getEntityManager().createQuery("select r from RegisUser r where username=:username");
        query.setParameter("username", username);
        RegisUser regisuser;
        try { 
            regisuser = (RegisUser) query.getSingleResult();
        }
        catch (Exception e){
            regisuser = null;
        }
        return regisuser;
    }

    @Override
    public RegisUser findByUserPass(String username, String password){
        Query query = this.getEntityManager().createNamedQuery("RegisUser.findByUserPass");
        query.setParameter("username", username);
        query.setParameter("password", password);
        RegisUser regisuser;

        try { // To prevent javax.persistence.NoResultException
            regisuser = (RegisUser) query.getSingleResult();
        }
        catch (Exception e){
            regisuser = null;
        }

        return regisuser;
    }

    @Override
    public RegisUser findByEmail(String email) {
        Query query = em.createQuery("select r from RegisUser r where r.email = :email");
        query.setParameter("email", email);
        RegisUser regisuser;
        try { 
            regisuser = (RegisUser) query.getSingleResult();
        }
        catch (Exception e){
            regisuser = null;
        }
        return regisuser;
    }
}

И это класс теста:

package edu.city.set.eia.citypress.mocking.beans;

import edu.city.set.eia.citypress.beans.RegisUserFacade;
import edu.city.set.eia.citypress.model.RegisUser;
import javax.persistence.Query;
import javax.persistence.EntityManager;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class RegisUserTest {

  private final transient EntityManager mockedEm =
          mock(EntityManager.class);
  private final transient Query mockedQuery =
          mock(Query.class);
  private static final String EMAIL = "test_email";
  private static final String INVALID_EMAIL = "test_email_invalid";

  @Before
  public final void setUp() {

    when(mockedEm.createQuery("Select r from RegisUser r where "
            + "r.email = :email")).thenReturn(mockedQuery);

    when(mockedQuery.setParameter("email", EMAIL)).thenReturn(mockedQuery);
    when(mockedQuery.setParameter("email", INVALID_EMAIL)).thenReturn(mockedQuery);
  }

  @Test
  public void testValidEmail() throws Exception {

    final RegisUser expectedUser = new RegisUser();
    expectedUser.setEmail(EMAIL);

    when(mockedQuery.setParameter("email", EMAIL)).thenReturn(mockedQuery);
    when(mockedQuery.getSingleResult()).thenReturn(expectedUser);

    RegisUserFacade bean = new RegisUserFacade();
    bean.setEntityManager(mockedEm);
    RegisUser user = bean.findByEmail(EMAIL);
    assertNotNull(user);
    assertEquals(EMAIL, user.getEmail());
  }

  @Test(expected = Exception.class)
  public void testInValidEmail() throws Exception {
    final RegisUser expectedUser = new RegisUser();
    expectedUser.setEmail(EMAIL);


    when(mockedQuery.setParameter("email", INVALID_EMAIL)).thenReturn(mockedQuery);
    when(mockedQuery.getSingleResult()).thenThrow(new Exception());

    RegisUserFacade bean = new RegisUserFacade();
    bean.setEntityManager(mockedEm);
    bean.findByEmail(INVALID_EMAIL);
  }
}

Я получаю ошибку testValidEmail caused an ERROR: java.lang.NullPointerException.

Ответы [ 3 ]

4 голосов
/ 16 декабря 2011

Я не знаком с Mockito, но похоже, что ваши строки не совпадают. Если Mockito чувствителен к регистру, то он объяснит, почему ваш query объект null.

when(mockedEm.createQuery("select r from RegisUser r where r.email = :email")).thenReturn(mockedQuery);

Обратите внимание на строчные буквы "s" в "select", которые соответствуют тому, что у вас есть в вашем бине.

1 голос
/ 25 мая 2018

Я столкнулся с той же проблемой, и я думаю, что проблема была более фундаментальной.Метод mockedQuery.setParameter должен модифицировать mockedQuery на месте, а не просто возвращать что-то.Я решил это, используя метод thenAnswer вместо метода thenReturn.

Mockito.when(mockedQuery.setParameter(anyString(), anyString())).then(
  new Answer<Query>() {
    public Query answer(InvocationOnMock invocation) {
      Object[] argumentsToTest = invocation.getArguments();
      if (!"email".equals((String) argumentsToTest[0])) {
        return findUserByIdQuery;
      }
      if (EMAIL.equals((String) argumentsToTest[1])) {
        Mockito.when(mockedQuery.getSingleResult()).thenReturn(expectedUser);
      } else {
        Mockito.when(mockedQuery.getSingleResult()).thenThrow(new Exception());
      }
      return mockedQuery;
    }
  }
);

Таким образом, вы можете поместить весь макет в блок @Before и оставить тесты для тестирования.Надеюсь, это поможет!

0 голосов
/ 16 декабря 2011

Если NullPointerException выброшено в query.setParameter("email", email);, то query равно null. Возможно, вам нужна завершающая строка ; в этой строке запроса.

...