Junit mockito @injectmock - компонент autowired sessionfactory

Я создал специальный applicationContext-test.xml, чтобы использовать его в своих тестовых классах.

applicationContext-test.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd">

    <context:property-placeholder location="classpath:db/database.properties"/>
    <context:annotation-config />


    <!--        DATASOURCE                      -->
    <jdbc:embedded-database id="h2dataSource" type="H2">
        <jdbc:script location="classpath:db/sql/create-db.sql" />
        <jdbc:script location="classpath:db/sql/insert-data.sql" />
    </jdbc:embedded-database>

    <!-- SESSION FACTORY -->
    <bean id="testSessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="h2dataSource"/>
        <property name="packagesToScan" value="com.medkhelifi.tutorials.todolist.models.entities"/>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect"> ${hibernate.dialect} </prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

    <!-- MUST have transaction manager, using aop and aspects  -->
    <bean id="testTransactionManager"
          class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="testSessionFactory" />
    </bean>
    <tx:annotation-driven transaction-manager="testTransactionManager" />
</beans>

Теперь я хочу использовать свой testSessionFactory в качестве Autowired Bean и внедрить его в свои макеты.

TodoDaoTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration (value = "classpath:/conf/applicationContext-test.xml")
public class TodoDaoTest {

    @Autowired
    @Mock
    SessionFactory testSessionFactory;

    @InjectMocks
    TodoDao todoDao;


    private boolean mockInitialized = false;

    @Before
    public void setUp(){
        if(!mockInitialized) {
            MockitoAnnotations.initMocks(this);
            mockInitialized = true;
        }    
    }

    @Test
    public void getTodosByUserIdShouldNotReturnNull(){
        User user = new User();
        assertNotNull(todoDao.getTodosByUserId(user.getId()));
    }
}

Это мой класс TodoDao TodoDao.java

@Component
@Transactional
public class TodoDao implements ITodoDao {

    @Autowired
    private SessionFactory sessionFactory;

    @Autowired
    private AuthenticationFacade authenticationFacade;

    @Override
    @PostFilter("filterObject.userByUserId == authenticationFacade.getAuthenticatedFacade()")
    public List<Todo> getTodosByUserId(int userId) {
        List todos;
        // this is line 30
        todos = sessionFactory.getCurrentSession().createQuery("from Todo where userId = ?").setParameter(0, userId).list(); // this is line 30
        return todos;
    }
}

Когда я выполняю свой тестовый метод, я получаю java.lang.NullPointerException at com.medkhelifi.tutorials.todolist.models.dao.TodoDao.getTodosByUserId(TodoDao.java:30) в строке 30 (как показано в классе TodoDao.java). Не знаю, упустил ли я что-то.

На какой строчке выкидывает NPE? Также вы можете опубликовать свою реализацию класса TodoDao?

Abubakkar 31.10.2018 13:39

Хорошо, я добавлю свою реализацию класса TodoDao.

medkhelifi 31.10.2018 13:40

Создайте Дао сами. Вы не вводите насмешки, вы записываете поведение. Итак, ваш TodoDao - это не фикция и не ваша сессионная фабрика. Так зачем усложнять ...

M. Deinum 31.10.2018 14:58
0
3
554
1

Ответы 1

Вы не определили поведение своего макета sessionFactory. Поэтому, когда ваш метод вызывает sessionFactory.getCurrentSession(), он возвращает ноль, и это приводит к NullPointerException.

Добавьте приведенный ниже код в свой тестовый метод getTodosByUserIdShouldNotReturnNull или ваш метод setUp, а также вам понадобится еще несколько фиктивных объектов:

when(sessionFactory.getCurrentSession()).thenReturn(sessionMock);when(sessionMock.createQuery("from Todo where userId = ?")).thenReturn(queryMock);

Но поскольку мой SessionFactory уже автоматически подключен к настоящему bean-компоненту, он не предполагает, что у него уже есть собственный сеанс ??

medkhelifi 31.10.2018 13:50

Почему вы хотите, чтобы ваш sessionFactory использовал настоящий bean-компонент для модульного тестирования? В модульном тестировании вы тестируете один конкретный класс и имитируете все остальные зависимые классы.

Abubakkar 31.10.2018 13:51

Я хочу использовать реальный компонент sessionFactory для тестирования с данными H2 (уже созданными в моих двух сценариях sql). Могу ли я сделать это только с фиктивными фиктивными бобами?

medkhelifi 31.10.2018 13:52

тогда это может быть проблема с вашим bean-компонентом sessionFactory, поскольку вы не хотите имитировать его.

Abubakkar 31.10.2018 13:54

У вас есть пример или руководство по тестированию с базой данных H2? В Google без результата

medkhelifi 31.10.2018 13:55

Проверьте это - это может помочь. baeldung.com/spring-jpa-test-in-memory-database

Abubakkar 31.10.2018 13:56

Другие вопросы по теме