Как смоделировать частный ответ с автопроводкой для отраженного частного метода - PullRequest
0 голосов
/ 04 июня 2019

Я тестирую публичный метод «сохранить в БД», который также отправляет некоторые из этих сохраненных данных, измененных в службу. Тест гарантирует, что он сохраняет то, что он получает, но отправляет измененные данные иначе. Проблема возникает, когда внутренний закрытый метод вызывает хранилище, для которого задано автоматическое подключение, а его ответ равен nullPointer, как в отражении того, что автоматически подключенное хранилище не инициализировано.

Итак, сначала для подтверждения того, что отвечает частный метод, я размышлял о частном методе. Я высмеял внутреннюю службу автоматической проводной связи с контролируемым ответом, но не нашел никакого результата о том, как установить, что поддельная служба отвечает на мое личное отражение.

Я все еще новичок в тестировании, поэтому, возможно, я допустил бы некоторые ошибки, объясняя, что сделал бы все возможное, чтобы исправить это и расширить тему ниже.


Это для открытого метода "X", который сохраняет что-то в базе данных (возвращает код для сохраненной вещи), затем делает некоторые другие вещи, а затем переходит к закрытому методу "Y", чтобы проверить некоторые данные и внутри этого частного метода. переходит к другому частному методу «Z», чтобы создать новые данные, извлекающие данные из другой службы «B» и из того, что они получили ранее, для отправки их внешней службе «A». Все это делается в одной и той же реализации класса "classImpl". Закрытый метод "Z" получает то же самое, что и метод "X", и он генерирует и возвращает данные, которые будут отправлены в сервисе "A", используя то, что он получил от "B".


@Test
@Rollback(false)
@Transactional(readOnly = false)
TEST{

testData testXData= new testData();
testXData.set()...
testXData.set()...
.......Generate data to be saved.

mockResponse controlledOutput = mock(mockResponse.class);

deliverInMockResponse deliverInMockResponse = new deliverInMockResponse();
deliverInMockResponse.set()...
deliverInMockResponse.set()...
.......Generate data to be delivered in the mockResponse.

when(controlledOutput.findByAnd(otherSomething)).thenReturn(deliverInMockResponse);

assertNotNull(testSaveMethodX(testXData));
String Something = "evalutaThis";
assertEquals(testXData.getSomething(),Something);

try{
      classImpl publicImpl = new classImpl();
      Method method =  classImpl.class.getDeclaredMethod("Z", testData.class);
      method.setAccessible(true);
      methodZResponse Zoutput = (methodZResponse) method.invoke(publicImpl, testXData);
      assertNotEquals(Zoutput.getSomething(),Something);
    }
    catch (Exception e){
      assertNotNull(null);
    }

}

Ответы [ 2 ]

0 голосов
/ 04 июня 2019

Если вы запускаете самодельный код отражения внутри теста, то, вероятно, протестированный код можно сделать лучше.

Не весь код автоматически тестируется юнитами. Чтобы иметь возможность проверить код, вы должны написать его определенным образом.

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

class MyDao {
   @Autowired
   private SomeService service;

   public void saveInDb() {
     // do something with db
     service.sendData();
   }
}

Поскольку автоматическое подключение не происходит во время теста (потому что в модульном тесте у вас нет Spring, чтобы сотворить его магию), вам сложно протестировать saveInDb метод

Однако этот код проблематичен и может быть реорганизован для лучшего модульного тестирования:

Итак, вот совет: не используйте Autowiring для полей, вместо этого перепишите код с помощью Constructor Injection:

class MyDao {
    private SomeService service;
    @Autowired // you can even omit this annotation in recent versions of spring
               // spring will understand what should be injected if there is only one 
               // constructor in the class
    public MyDao(SomeService service) {
        this.service = service;
    }
} 

Если вы чувствуете, что это много кода, вы даже можете использовать проект Lombok для генерации конструктора для вас, но это выходит за рамки вопроса ...

Так или иначе, у вас теперь есть класс с четко определенным списком зависимостей, который должен быть указан в тесте, который пытается создать экземпляр этого класса.

Здесь упрощается юнит-тестирование:

  SomeService someService = Mockito.mock(SomeService.class);
  MyDao underTest = new MyDao(someService);

В отличие от предыдущего ответа Юаня Цинфея, я не предлагаю использовать такие инструменты, как PowerMock / PowerMockito, рассмотрите возможность их использования, только если вы не можете вносить изменения в тестируемый код (обычно это верно для старых проектов, написанных без тестирования в ум)

0 голосов
/ 04 июня 2019

Что касается проверки или тестирования частного метода, я бы предпочел, чтобы вы попробовали PowerMock вместо того, чтобы написать отражение самостоятельно. здесь - хорошее руководство.Также Личный метод с использованием PowerMockito

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...