2017-02-15 10 views
0

У меня есть проект, который использует Spring MVC. Я пытаюсь написать модульные тесты для сервисного модуля, , который находится в архитектуре проекта. Все классы обслуживания распространяются от суперкласса под названием «BaseService». BaseService как это:как издеваться над суперклассом, который ввел зависимости

public abstract class BaseService { 

private static final Logger logger = LoggerFactory.getLogger(BaseService.class); 

@Autowired(required = true) 
private HttpServletRequest request; 

@Autowired 
private ReloadableResourceBundleMessageSource messageSource; 

/* 
* Injecting Mapper 
*/ 
@Resource 
private Mapper mapper; 
... 

public <T extends BaseBVO, S extends BaseVO> T voToBvo (S vo, Class<?  extends BaseBVO> bvoClass) { 

    if (vo != null) 
    { 
     return (T) mapper.map(vo , bvoClass); 
    } 
    else 
    { 
     return null; 
    } 
} 

теперь у меня есть метод в служебном модуле, которые используют метод:

"voToBvo (S vo, Class<?  extends BaseBVO> bvoClass") 

так:

public List<AdcOptionBVO> findOptionByAyantDroitIdAndProduitId (Long idAyantDroit, String idProduit) { 

    .... 

     list = listVoToBvo(adcList , AdcOptionBVO.class); 
     logger.info("Returning List of ayrp count= {}" , list.size()); 

    return list; 
} 

Мой тест выглядит так:

@RunWith(MockitoJUnitRunner.class) 
public class AdcServiceImplTest{ 

@Mock 
private Mapper mapper; 

    @Test 
public void shouldSuccessFindOptionByAyantDroitIdandProduitId() { 
    //Given 
    List<AdcVO> adcVOList = new ArrayList<>(); 
    adcVOList.add(new AdcVO()); 

    List<AdcOptionBVO> listAdcOptionBVO = new ArrayList<>(); 
    listAdcOptionBVO.add(new AdcOptionBVO()); 

    List<BaseBVO> baseBVOs = new ArrayList<>(); 

    //When 
    when(repository 
      .finAdcByOptionOrderByRUAndPrio(anyLong(), anyString())).thenReturn(adcVOList); 

    when(baseService.listVoToBvo(adcVOList, AdcOptionBVO.class)).thenReturn(baseBVOs); 


    //Then 
    assertEquals(adcService 
      .findOptionByAyantDroitIdAndProduitId(anyLong(), anyString()).size(), adcVOList.size()); 

} 
} 

Я получаю java.lang.NullPointerException в BaseService.java при вызове mapper.

@Resource 
private Mapper mapper; 

переводчик имеет значение null!

Я хочу издеваться метод:

listVoToBvo(adcList , AdcOptionBVO.class); 

Пожалуйста, помогите.

ответ

1

Решения добавить конструктор для Abstarct класса с закачиваемым параметром, в моем случае (картограф), то при вызове службы super(mapper); в конструкторе службы поэтому в тестах я издеваюсь Mapper картографа, то я создание экземпляра мой класс в @Before, поэтому преобразователь переходит к классу abstarct как Mock, а не null. Он отлично работает для меня. Я надеюсь, что его claire

1

Поскольку ваш тест в настоящее время настроен, ни один из введенных элементов базового класса не вводится. Есть два способа, которые можно использовать, чтобы исправить это:

  1. Запуск с использованием Spring тест бегун (названный SpringJUnit4ClassRunner.class). Это отлично подходит для тестирования интеграции, которое выходит за рамки.
  2. Выполните инъекцию вручную. Используйте отражение и задайте обработчик в классе BaseService макету.

Используйте метод 2.

Создать программу, которая используется для тестирования, который устанавливает элемент данных с помощью отражения. Выполните поиск по Google для «установить родительское переменное переменное отражение java» или что-то близкое к этому, и вы найдете пример reflection code.d Утилита должна обернуть код отражения и взять параметры для имени члена данных, объекта класса, ссылку на объект, в котором нужно установить значение, и все, что необходимо для выполнения отражения.

Другой вариант - найти утилиту для отражения (google, apache и spring), которая должна иметь один.

Вот (не функционирует) пример:

public static void setFieldObject(
    final String fieldName, 
    final Object fieldValue, 
    final Object targetObject, 
    final Class targetClass) 
throws 
    NoSuchFieldException, 
    IllegalAccessException 
{ 
    final Field targetField; 

    targetField = targetClass.getDeclaredField(fieldName); 
    targetField.setAccessible(true); 

    targetField.set(
     targetObject, 
     fieldValue); 
} 
0

На самом деле ваш код как-то не очень понятно, однако использование Mockito издеваться autowired поля не так уж сложно, нужно всего лишь следовать правильные шаги ,

Давайте предположим, что мы хотим создать модульный тест для BaseService:

public class BaseServiceTest { 

    private static final BaseVO TEST_BaseVO = //intialize here...; 
    private static final BaseBVO TEST_BaseBVO = //intialize here...; 

    private static final BaseBVO TEST_BaseBVO_RESULT = //intialize here...; 

    @InjectMocks 
    private BaseService baseService; 

    @Mock 
    private HttpServletRequest request; 

    @Mock 
    private ReloadableResourceBundleMessageSource messageSource; 

    @Mock 
    private Mapper mapper; 

    @BeforeMethod 
    public void initMocks(){ 
     //This line of code is so important!! to initialize annotated fields. without it these fields would be null. 
     //Or just annotate this class with @RunWith(MockitoJUnitRunner.class) 

     MockitoAnnotations.initMocks(this); 

     //Here all fields annotated with @Mock or @Spy should be initialize and injected into BaseService. 
    } 

    @Test 
    public void voToBvo_should_return_null_when_vo_is_null(){ 

     //Call testing method 
     BaseBVO result = baseService.voToBvo(null, TEST_BaseBVO.class); 

     //Assertions 
     Assert.assertNull(result); 
    } 

    @Test 
    public void voToBvo_should_not_return_null_when_vo_is_not_null(){ 

     //Mock calls 
     Mockito.doReturn(TEST_BaseBVO_RESULT).when(mapper).map(TEST_BaseVO, TEST_BaseBVO.class) 

     //Call testing method 
     BaseBVO result = baseService.voToBvo(TEST_BaseVO, TEST_BaseBVO.class); 

     //Assertions 
     Assert.assertNotNull(result); 
     Assert.assertEquals(TEST_BaseBVO_RESULT, result); 
    } 
} 

Это может звучать для вас, что этот тест блок глупо (на самом деле это глупо: р), но она описывает основные шаги создать успешный UT с использованием Mockito, а также как предотвратить NPE.

3

Предлагаю вам сначала сменить в своем BaseService файл. Изменить способ написания @Autowired следующим

private HttpServletRequest request; 
@Autowired(required = true) 
public void setSpellChecker(HttpServletRequest request){ 
    this.request = request; 
} 

@Autowired 
private ReloadableResourceBundleMessageSource messageSource; 
public void setSpellChecker(ReloadableResourceBundleMessageSource messageSource){ 
    this.messageSource = messageSource; 
} 

И когда вы сделаете это, теперь вы можете легко достичь тест-кейсы с зависимостью.