Пытаюсь издеваться над сервисом, но получаю исключение NullPointerException (JUNIT / MOCKITO) - PullRequest
1 голос
/ 04 августа 2020

Я новичок в модульном тестировании Junit и Mockito. Мне нужно провести модульное тестирование метода "processFiles (final File folder)"

Поскольку я вызываю другую службу внутри этого метода, называемого myService.isFileOk (data), я думаю, мне нужно издеваться над этой службой, чтобы сделать он возвращает истину.

Но когда я запускаю свой тест, я получаю исключение нулевого указателя.

Это часть кода из метода processFiles:

  @EJB
  private transient MyService myService;

  public void processFiles(final File folder)
  {
     
      File[] fileNames = folder.listFiles();
      List<String> lines = new ArrayList<>();
      boolean isFirstFile = true;
      try
      {
          for (File file : fileNames)
          {
                  List<String> l = readContent(file, isFirstFile);
                  l.forEach(i -> lines.add(i));
                  isFirstFile = false;     
          }

          String[] data = lines.get(0).trim().split(";");
          if (!this.myservice.isFileOk(data))
          {
            // ...
          }
          else
          {
              // ...
          }
      }
      catch (IOException e)
      {
          e.printStackTrace();
      }
  }

И вот как я пытаюсь протестировать свой метод processFile

    @Mock
    public MyService myService ;

    @Rule
    public TemporaryFolder temporaryFolder = new TemporaryFolder();


    @Test
    public void testWrite2() throws IOException {

        final File tempFile1 = temporaryFolder.newFile("tempFile.txt");
        final File tempFile2 = temporaryFolder.newFile("tempFile2.txt");

        String[] data = {"a", "b" , "c" , "d"} ;
        this.myService = new MyService();


       MyService myService = Mockito.mock(MyService.class);
 
       when(myService.isFileOk(data)).thenReturn(true);


//... myclass.processFiles(file);
    }

Вы знаете, как мне приступить к имитации isFileOk? Заранее большое спасибо за вашу помощь

Ответы [ 2 ]

0 голосов
/ 04 августа 2020

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

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

По сути, вы ищете EJB-эквивалент аннотации Spring «@RunWith (SpringRunner.class)», которая выполняет инъекции при выполнении ваших тестовых примеров.

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

0 голосов
/ 04 августа 2020

Что вам нужно сделать, так это передать макет классу, содержащему экземпляр, а также использовать сопоставители:

https://www.javadoc.io/doc/org.mockito/mockito-core/1.9.5/org/mockito/Matchers.html

when(myService.isFileOk(eq(data))).thenReturn(true);

У вас есть два раза определял также MyService. Один раз глобально и один раз локально внутри метода. Возможно, вам стоит подумать об удалении одного из двух.

Вы можете использовать отражение, чтобы установить private transient MyService myService; в MyClass

Field myServiceField = myclass.getClass().getDeclaredField("myService");
myServiceField.setAccessible(true);
f1.set(myClass, mock);

А затем вызвать:

myclass.processFiles(file);

Теперь ваш макет должен быть инициализирован.

...