Mockito注释和方法调用之间的区别

问题描述 投票:0回答:2

我有一个关于在Java中使用Mockito的问题。我将附上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());
    }
}

当我使用第二个验证方法时,我得到一个错误,该方法永远不会在模拟上调用,所以我想知道我错过了什么?我在网上查了教程,有些使用注释,有些使用方法调用,但如果我没有弄错,它们应该是一样的,那么我在这里缺少什么?

java testing junit annotations mockito
2个回答
1
投票

在你的第一个例子中,@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);

注意:即使你从setup方法中删除verify(testDB).getActivites(),测试也会失败它的断言,除非你实际上向DatabaseModel提供了模拟的controller


0
投票

你在第二版中用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();
}
© www.soinside.com 2019 - 2024. All rights reserved.