Метод суперкласса Mockito Mock для зависимости - PullRequest
0 голосов
/ 27 мая 2020

У меня есть класс с такой зависимостью:

public class Subject {
   private Dependency dep;

   public Subject(Dependency d) {
     this.dep = d;
   }

   public Result test() {
     return dep.validate(); 
   }
}

Мой класс Dependency на самом деле является базовым классом. Это выглядит так:

public Class Dependency extends Base {
   void method1() {

   }

}

Базовый класс - это абстрактный класс, подобный этому:

public abstract class Base {
  protected abstract method1() {
  }

  //This is the method I want to mock
  public Result validate() {
  }
}

Теперь я пытаюсь протестировать свой класс Subject:

public class SubjectTest {
  @Mock
  private Dependency dep;

  private Subject subject;

  @Before
  public void setup() {
   initMocks(this);
   subject = new Subject(dep);
  }

  @Test
  public void test() {
    when(dep.validate()).thenReturn(Result.VALID);  //validate is a super class method

    subject.test();
  }
}

Когда я пытаюсь имитировать метод в when(dep.validate()).thenReturn(Result.VALID), он фактически вызывает метод настоящего суперкласса и генерирует исключение NullPointerException.

Как я могу решить эту проблему? Я знаю, что предпочтение следует отдавать композиции, а не наследованию, но я не контролирую класс Dependency. Итак, я не могу go и изменить его.

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

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Невозможно воспроизвести ошибку с Java: 8, junit: 4.12 и mockito: 2.1.0, опубликованный код ведет себя правильно. Возможно, дважды проверьте версии.

1 голос
/ 27 мая 2020

Вероятно, вы что-то напутали в настройке. Я попытался воспроизвести ваш случай, и он работает в моей настройке:

package com.example.demo;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;

enum Result {
    VALID, INVALID;
}
abstract class Base {
    protected abstract void method1();

    public Result validate() {
        return Result.INVALID;
    }
}
class Dependency extends Base {
    public void method1() {

    }
}
class Subject {
    private Dependency dep;

    public Subject(Dependency d) {
        this.dep = d;
    }

    public Result test() {
        return dep.validate();
    }
}

public class SampleTest {

    private Dependency dep = Mockito.mock(Dependency.class);

    private Subject subject;


    @Test
    public void testMe() {
        subject = new Subject(dep);
        when(dep.validate()).thenReturn(Result.VALID);  //validate is a super class method

        Result result = subject.test();
        assertThat(result, equalTo(Result.VALID));
    }

}

Mockito в целом должен поддерживать такой вариант использования без каких-либо проблем.

Я подозреваю, что это что-то с аннотацией "initMocks" / или, возможно, @Mock, для которой требуется специальный бегун / расширение, если вы используете JUnit 5, что не показано в вопросе.

Я намеренно избегал этих "расширенных" в приведенном выше примере, чтобы создать минимально воспроизводимый пример. Проверьте этот код и обновите, работает ли он у вас.

PS: для теста использовалось ядро ​​Mockito: 3.3.3

...