mockito@injectmocks是如何工作的

c3frrgcw  于 2021-06-26  发布在  Java
关注(0)|答案(1)|浏览(391)

通过@mock和@injectmocks之间的区别,我了解到@injectmocks被用作创建示例的注解,并将用@mock创建的mock注入其中。我想我不明白它是怎么工作的。
我有一个例子代码,我想问你2个问题,以便直奔我不清楚的要点。问题在最后。
我有一个接口:

public interface SimpleAgenda {

    public List<String> getAppointments();

    public String getAppointment(Date d);

    public void addAppointments(Date d, String label);

}

以及实现此接口的类:

public class MyAgenda implements SimpleAgenda {

    private Map<String, String> appointments;

    @Override
    public List<String> getAppointments() {
        List<String> lst = new ArrayList<String>();
        System.out.println(this.appointments == null);
        for (String key : this.appointments.keySet()) {
            String label = this.appointments.get(key);
            lst.add(label);
        }

        return lst;
    }

    @Override
    public String getAppointment(Date d) {
        String dateString = d.toString();
        String app = this.appointments.get(dateString);

        return app;
    }

    @Override
    public void addAppointments(Date d, String label) {
        // TODO Auto-generated method stub
        // this behavior is not implemented yet in this class
    }

}

最后我有了测试课:

// @RunWith attaches a runner with the test class to initialize the test data
@RunWith(MockitoJUnitRunner.class)
public class AgendaTest {

    private static final String LABEL = "This is a mock appointment for: ";

    // @InjectMocks annotation is used to create and inject the mock object
    @InjectMocks
    MyAgenda agenda = new MyAgenda();

    // @Mock annotation is used to create the mock object to be injected
    @Mock
    Map<String, String> mockedAppointments;

    @Before
    public void createMocks() {
        Date d1 = (new GregorianCalendar(120, 4, 15)).getTime();
        Date d2 = (new GregorianCalendar(119, 7, 31)).getTime();

        String key;

        key = d1.toString();
        // add the mocked behavior of for a set of given dates
        when(mockedAppointments.get(key)).thenReturn(LABEL + key);

        key = d2.toString();
        // 1. add the mocked behavior of for a set of given dates.
        // 2. Strict stubbing that requires that all declared stubs are actually used
        //    the statement lenient() relax this requirement. Check the manual. 
        lenient().when(mockedAppointments.get(key)).thenReturn(LABEL + key);

        when(mockedAppointments.size()).thenReturn(2);
    }

    @Test
    public void mockTest() {
        for (String key : mockedAppointments.keySet()) {
            String v = mockedAppointments.get(key);
// Do not worry, we will never reach this line. We are querying the object on 
// method that was not mocked (i.e. keySet).            
            Assert.fail();
        }

        int size = mockedAppointments.size();

        Assert.assertEquals(2, size);
    }

    @Test
    public void simpleTest() {
        int appCounter = agenda.getAppointments().size();
// Do not expect that appCounter is 2 (or more in general different than 0) ... 
// we are actually querying an object that was not mocked!!!
// See the details of the implementation of the method: MyAgenda.getAppointments()
        Assert.assertEquals(0, appCounter);
    }

以下是我的问题:
mockTest() 当我打电话的时候 mockedAppointments.keySet() 它返回一个空集。。。我的问题是:为什么 mockedAppointments.keySet() 不会扔垃圾 nullPointerException (仅声明MockedAppoints)?也许是因为这是个玩笑?如果原因是这样的,为什么一个模拟不抛出“nullpointerexception”?
simpleTest() 我们有 agenda.getAppointments().size(); ; agenda.getAppointments() 包含 System.out.println(this.appointments == null); 这行打印的“false”是我保留的@injectmocks注解,否则是“true”,但是为什么呢?在第一种情况下(保留@injectmocks),“agenda”的“appointments”属性在哪里初始化?是因为我们注入了 mockedAppointments 你喜欢吗?如果是,mockito是否仅基于测试类中定义的mock类型和中定义的属性类型来执行此操作 MyAgenda ?

woobm2wo

woobm2wo1#

为什么mockedAppoints.keyset()不抛出nullpointerexception(mockedAppoints只是声明的)?也许是因为这是个玩笑?如果原因是这样的,为什么一个模拟不抛出“nullpointerexception”?
答案是:因为 mockedAppointments.keySet().size 是0和 mockedAppointments.keySet() 是空的,是模仿的行为
2.0 qn system.out.println(this.appointments==null);行打印“false”是我保留@injectmocks注解,否则“true”,但为什么?
答案是:在junit或mockito系统中,println不起作用,而是使用logger。
2.1 qn在第一种情况下(保留@injectmocks),“agenda”的“appointments”属性在哪里初始化?
答案是:它是模仿类,例如列出它初始化为0,并保持值为空,除此之外

@InjectMocks
private MyAgenda agenda;

应该这样宣布
2.2qn它的初始化是因为我们将mockedappoints的值注入它吗?
答案是:mockedAppoints和agenda没有任何联系,除此之外,你可以使用mocked @Mocks ,它起作用了。

@Mocks
 private MyAgenda agenda;

相关问题