Mockito-NullpointerException при stubbing метод

поэтому я начал писать тесты для нашего Java-Spring-проекта.

Я использую JUnit и Mockito. Говорят, что когда я использую when()...опция thenReturn () я могу издеваться над сервисами, не имитируя их или около того. Итак, что я хочу сделать, это установить:

when(classIwantToTest.object.get().methodWhichReturnsAList(input))thenReturn(ListcreatedInsideTheTestClass)  

но независимо от того, когда-предложение я делаю, я всегда получаю исключение NullpointerException, что, конечно, имеет смысл, потому что input равно null.

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

when(object.method()).thenReturn(true)

там я также получаю Nullpointer, потому что метод нуждается в переменной, которая не установлена.

но я хочу использовать when ()..thenReturn (), чтобы обойти создание этой переменной и так далее. Я просто хочу убедиться, что если какой-либо класс вызывает этот метод, то, несмотря ни на что, просто верните true или список выше.

это в основном недоразумение с моей стороны, или есть что-то еще не так?

код:

public class classIWantToTest implements classIWantToTestFacade{
        @Autowired
        private SomeService myService;

        @Override
        public Optional<OutputData> getInformations(final InputData inputData) {
            final Optional<OutputData> data = myService.getListWithData(inputData);
            if (data.isPresent()) {
                final List<ItemData> allData = data.get().getItemDatas();
                    //do something with the data and allData
                return data;
            }

            return Optional.absent();
        }   
}

и вот мой тестовый класс:

public class Test {

    private InputData inputdata;

    private ClassUnderTest classUnderTest;

    final List<ItemData> allData = new ArrayList<ItemData>();

    @Mock
    private DeliveryItemData item1;

    @Mock
    private DeliveryItemData item2;



    @Mock
    private SomeService myService;


    @Before
    public void setUp() throws Exception {
        classUnderTest = new ClassUnderTest();
        myService = mock(myService.class); 
        classUnderTest.setService(myService);
        item1 = mock(DeliveryItemData.class);
        item2 = mock(DeliveryItemData.class);

    }


    @Test
    public void test_sort() {
        createData();
        when(myService.getListWithData(inputdata).get().getItemDatas());

        when(item1.hasSomething()).thenReturn(true);
        when(item2.hasSomething()).thenReturn(false);

    }

    public void createData() {
        item1.setSomeValue("val");
        item2.setSomeOtherValue("test");

        item2.setSomeValue("val");
        item2.setSomeOtherValue("value");

        allData.add(item1);
        allData.add(item2);


}

10 ответов


возвращаемое значение по умолчанию методов, которые вы еще не заглушили, -false для логических методов, пустая коллекция или карта для методов, возвращающих коллекции или карты и null иначе.

это также относится к вызовам метода внутри when(...). В тебе пример when(myService.getListWithData(inputData).get()) вызовет исключение NullPointerException, потому что myService.getListWithData(inputData) is null - он не был заглушен раньше.

один из вариантов-создать насмешки для всех промежуточных возвращаемых значений и заглушить их перед использованием. Для пример:

ListWithData listWithData = mock(ListWithData.class);
when(listWithData.get()).thenReturn(item1);
when(myService.getListWithData()).thenReturn(listWithData);

или, альтернативно, вы можете указать другой ответ по умолчанию при создании макета, чтобы методы возвращали новый макет вместо null:RETURNS_DEEP_STUBS

SomeService myService = mock(SomeService.class, Mockito.RETURNS_DEEP_STUBS);
when(myService.getListWithData().get()).thenReturn(item1);

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

надеюсь, это поможет. Просто обратите внимание, что ваш пример кода, похоже, имеет больше проблем, таких как отсутствует assert или verify операторы и вызывающие сеттеры на mocks (которые не имеют никакого эффекта).


у меня была эта проблема, и моя проблема заключалась в том, что я вызывал свой метод с any() вместо anyInt(). Поэтому я сказал:

doAnswer(...).with(myMockObject).thisFuncTakesAnInt(any())

и мне пришлось изменить его на:

doAnswer(...).with(myMockObject).thisFuncTakesAnInt(anyInt())

Я понятия не имею, почему это вызвало исключение NullPointerException. Может, это поможет следующей бедняжке.


У меня была та же проблема, и моя проблема заключалась в том, что я не аннотировал класс должным образом, используя @RunWith. В вашем примере, убедитесь, что у вас есть:

@RunWith(MockitoJUnitRunner.class)
public class Test {
...

Как только я это сделал, NullPointerExceptions исчезли.


угловой делу:
Если вы используете Scala и вы пытаетесь создать any matcher на классе, вы получите бесполезный NPE.

учитывая case class ValueClass(value: Int) extends AnyVal, что вы хотите сделать, это ValueClass(anyInt) вместо any[ValueClass]

when(mock.someMethod(ValueClass(anyInt))).thenAnswer {
   ...
   val v  = ValueClass(invocation.getArguments()(0).asInstanceOf[Int])
   ...
}

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


для меня причина, по которой я получал NPE, заключается в том, что я использовал Mockito.any() когда издеваются над примитивами. Я обнаружил, что, переключившись на использование правильного варианта из mockito, избавляется от ошибок.

например, чтобы издеваться над функцией, которая принимает примитивный long в качестве параметра, вместо того, чтобы использовать any(), вы должны быть более конкретными и заменить, что с any(Long.class) или Mockito.anyLong().

надеюсь, что это кому-то поможет.

Ура


@RunWith(MockitoJUnitRunner.class) //(OR) PowerMockRunner.class

@PrepareForTest({UpdateUtil.class,Log.class,SharedPreferences.class,SharedPreferences.Editor.class})
public class InstallationTest extends TestCase{

@Mock
Context mockContext;
@Mock
SharedPreferences mSharedPreferences;
@Mock
SharedPreferences.Editor mSharedPreferenceEdtor;

@Before
public void setUp() throws Exception
{
//        mockContext = Mockito.mock(Context.class);
//        mSharedPreferences = Mockito.mock(SharedPreferences.class);
//        mSharedPreferenceEdtor = Mockito.mock(SharedPreferences.Editor.class);
    when(mockContext.getSharedPreferences(Mockito.anyString(),Mockito.anyInt())).thenReturn(mSharedPreferences);
    when(mSharedPreferences.edit()).thenReturn(mSharedPreferenceEdtor);
    when(mSharedPreferenceEdtor.remove(Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
    when(mSharedPreferenceEdtor.putString(Mockito.anyString(),Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
}

@Test
public void deletePreferencesTest() throws Exception {

 }
}

все вышеуказанные прокомментированные коды не требуются { mockContext = Mockito.mock(Context.class); }, если вы используете @Mock аннотации Context mockContext;

 @Mock 
 Context mockContext; 

но это будет работать, если вы используете @RunWith (MockitoJUnitRunner.класс) только. В соответствии с Mockito вы можете создать макет объекта, используя @ Mock или Mockito.mock (контекст.класс); ,

Я получил исключение NullpointerException из-за использования @RunWith(PowerMockRunner.class), вместо этого я перешел на @RunWith (MockitoJUnitRunner.класс) он отлично работает


для будущих читателей другой причиной для NPE при использовании mocks является забывание инициализировать mocks следующим образом:

@Mock
SomeMock someMock;

@InjectMocks
SomeService someService;

@Before
public void setup(){
    MockitoAnnotations.initMocks(this); //without this you will get NPE
}

@Test
public void someTest(){
    Mockito.when(someMock.someMethod()).thenReturn("some result");
   // ...
}

столкнулся с той же проблемой, решение, которое сработало для меня:

вместо того, чтобы издеваться над интерфейсом службы, я использовал @InjectMocks для издевательства над реализацией службы:

@InjectMocks
private exampleServiceImpl exampleServiceMock;

вместо :

@Mock
private exampleService exampleServiceMock;

Эд Уэбб ответ помогли в моем случае. И вместо этого вы также можете попробовать add

  @Rule public Mocks mocks = new Mocks(this);

Если вы @RunWith(JUnit4.class).


в моем случае я пропустил add first

PowerMockito.spy(ClassWhichNeedToBeStaticMocked.class);

Так что это может быть полезно для тех, кто видит такую ошибку

java.lang.NullPointerException
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.addAnswersForStubbing(PowerMockitoStubberImpl.java:67)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:42)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:112)