Разница в мокито между аннотациями и вызовами методов - PullRequest
0 голосов
/ 06 марта 2019

У меня есть вопрос об использовании Mockito в Java.Я прикреплю 2 блока аналогичного кода: первый, который отлично работает

package controller;

import model.DatabaseModel;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;

public class TestController {

    JSONObject jsonObj1;
    JSONArray testArr;
    @Mock
    private DatabaseModel testDB;

    @InjectMocks
    private Controller controller;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        jsonObj1 = new JSONObject();
        jsonObj1.put("name", "Bar");
        testArr = new JSONArray();
        testArr.put(jsonObj1);
        when(testDB.getActivites()).thenReturn(testArr);
    }

    @Test
    public void testServerCon() {
        ArrayList<String> testServer = new ArrayList<>();
        testServer.add("Bar");
        assertEquals(testServer, controller.getAllActivites());
    }
}

и второй, который действительно не работает:

package controller;

import model.DatabaseModel;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.ArrayList;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;

public class TestController2 {
    JSONObject jsonObj1;
    JSONArray testArr;
    DatabaseModel testDB;
    Controller controller;

    @Before
    public void setup() {

        jsonObj1=new JSONObject();
        jsonObj1.put("name", "Bar");
        testArr=new JSONArray();
        testArr.put(jsonObj1);
        controller=new Controller();
        testDB=mock(DatabaseModel.class);
        when(testDB.getActivites()).thenReturn(testArr);
        verify(testDB).getActivites();

    }

    @Test
    public void testServerCon(){

        ArrayList<String> testServer=new ArrayList<>();
        testServer.add("Bar");
        assertEquals(testServer, controller.getAllActivites());
    }
}

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

Ответы [ 2 ]

1 голос
/ 06 марта 2019

В вашем первом примере аннотация @InjectMocks приводит к тому, что экземпляр Controller будет инъецирован с имитированным DatabaseModel.

Во втором примере вы создаете Controller вроде бы так ...

controller=new Controller();

... но вы никогда не впрыснете поддельные Database Model в этот экземпляр Controller.Поэтому, когда вы вызываете controller.getAllActivites(), ваш контроллер никогда не использует поддельные DatabaseModel.Вы можете достичь того же результата, что и в первом примере, если вы можете ввести DatabaseModel в свой Controller.Например:

testDB=mock(DatabaseModel.class);

// constructor injection
controller=new Controller(testDB);

// setter injection
controller=new Controller();
controller.setDatabaseModel(testDB);

Примечание: даже если вы удалите verify(testDB).getActivites() из метода настройки, тест не сможет подтвердить свое утверждение, если вы фактически не предоставите имитируемый DatabaseModel для controller.

0 голосов
/ 06 марта 2019

Вы делаете verify в методе setup во второй версии ...

@Before
public void setup() {

    jsonObj1=new JSONObject();
    jsonObj1.put("name", "Bar");
    testArr=new JSONArray();
    testArr.put(jsonObj1);
    controller=new Controller();
    testDB=mock(DatabaseModel.class);
    when(testDB.getActivites()).thenReturn(testArr);
    verify(testDB).getActivites(); // REMOVE THIS LINE

}

К этому времени ничего бы не вызывалось, отсюда и ошибка.

Возможно, вы захотите переместить эту строку в свой метод тестирования, например ...

@Test
public void testServerCon(){

    ArrayList<String> testServer=new ArrayList<>();
    testServer.add("Bar");
    assertEquals(testServer, controller.getAllActivites());
    verify(testDB).getActivites();
}
...