Весенняя загрузка JUnit тест BeanFactory.исключение нулевого указателя getBean

#java #spring-boot #junit #reflection #nullpointerexception

Вопрос:

У меня есть функция, которую я пытаюсь протестировать с помощью JUnit, но я не могу найти, как преодолеть эту проблему:

в службе у меня есть эта декларация:

 Warning_Log Warning_Log_FRAGMENT = beanFactory.getBean(Warning_Log.class);
 

Я попытался объявить объект BeanFactory в тестовом классе с аннотацией @MockBean, но получил исключение с нулевым указателем.

Вишенкой на торте является то, что функция, которую я тестирую, является частной, поэтому я использую отражение для доступа к ней.

Вы знаете, как работает бобовый завод(Warning_Log.class) может быть реализована в тестовой функции junit?

Редактировать

код в сервисе следующий:

 try {
        JSONObject jsonFragmentRequestWarning_Log = new JSONObject();
        jsonFragmentRequestWarning_Log.put("messaggio", "Create Session Blocked [Assertion=" policy.getString("name") "]|[flag_block_create_session=" gateway.flag_block_create_session "]|[ApplicationName=" Request.getHeader("ApplicationName") "]|[ErroreDaRitornare=" erroreDaRitornare "]");
        jsonFragmentRequestWarning_Log.put("sanitize", false);

        Warning_Log Warning_Log_FRAGMENT = beanFactory.getBean(Warning_Log.class);
        
        String sFragmentResponseWarning_Log = Warning_Log_FRAGMENT.warning_Log(jsonFragmentRequestWarning_Log.toString(), httpHeaders);

        JSONObject jsonFragmentResponseWarning_Log = new JSONObject(sFragmentResponseWarning_Log);

    }
 

фабрика бобов автоматически подключается к сервису следующим образом:

 @Autowired
private BeanFactory beanFactory;
 

ПРАВКА 2
Это то, что я попробовал в функции junit, что привело к исключению нулевого указателя:

 Field bf = clazz.getClass().getDeclaredField("beanFactory");
bf.setAccessible(true);
bf.set(clazz, beanfactory);
 

И beanfactory объявляется следующим образом в начале класса:

 @MockBean
private BeanFactory beanfactory;
 

Комментарии:

1. Добро пожаловать в SO. Можете ли вы предоставить скелет класса, который использует эту строку? Где вы вызываете эту строку, из какого метода? Как создается экземпляр BeanFactory в классе? В общем, BeanFactory, вероятно, является контекстом приложения spring, и обычно на самом деле не имеет смысла использовать ссылку на контекст приложения в вашем бизнес-коде…

2. @MarkBramnik Спасибо за быструю обратную связь, я добавил правку в исходный вопрос, если мне нужно предоставить более подробную информацию, пожалуйста, дайте мне знать.

3. Можете ли вы также добавить соответствующий код из модульного теста?

4. @ErikKarlstrand я добавил код junit, для которого я использовал для установки BeanFactory

5. Даже если метод, который вы пытаетесь протестировать, заключается private в том, что нет необходимости использовать отражение для доступа к public полю. В настоящее время ваш @MockBean телефон вообще не используется. Вместо того, чтобы использовать отражение, просто используйте beanFactory то, над чем вы насмехались.

Ответ №1:

Скажите, что у вас есть следующий класс:

 @Service
public class MyClass {

    @Autowired
    private BeanFactory beanFactory;

    /*
     * Some more code
     */
}
 

А затем вы хотите создать некоторые модульные тесты для этого класса, такие как этот:

 @RunWith(SpringRunner.class)
public class MyClassTest {

    @MockBean
    private BeanFactory beanFactoryMock;

    @Autowired
    private MyClass myClass;

    @Test
    public void testMyClass() {

        // Since we have annotated our BeanFactory with @MockBean
        // this is now the instance that will be used by our class-under-test
        Mockito.when(beanFactoryMock.getBean(Warning_Log.class))
            .thenReturn(...);
    }
 

Это общая идея. Если у вас есть поле, подверженное внедрению зависимостей, вам не нужно использовать отражение, чтобы получить к нему доступ в модульных тестах. MockBean Аннотация сообщит контейнеру IoC использовать ваш издевательский класс везде, где он вводится.

Комментарии:

1. Я ценю ответ, но это то, что я пытался сделать, и я получаю исключение нулевого указателя

2. Вы комментируете свой тестовый класс с @RunWith(SpringRunner.class) помощью ?

3. Да, я понимаю, во время отладки я вижу в службе, что BeanFactory является издевательским, но я получаю нулевой указатель на эту строку строки sFragmentResponseWarning_Log = Warning_Log_FRAGMENT.warning_Log(jsonFragmentRequestWarning_Log.toString (), HttpHeaders);

4. Если вы проверяете переменные во время отладки, должно быть довольно просто определить, что равно нулю. Мои деньги на этом Warning_Log_FRAGMENT . Чтобы исправить это, вам нужно создать его экземпляр и вернуть его при beanFactory вызове

5. Да, точно, макет работает нормально, это был фрагмент Warning_Log_FRAGMENT, которому нужны были некоторые параметры? большое спасибо! я приму ваш ответ как решенный!