Java Mockito mock对象有多个相同类型的属性

Java Mockito mock对象有多个相同类型的属性

业务类

public class TestServiceImpl {
    
    @Autowired
    @Qualifier("restTemplateA")
    private RestTemplate restTemplateA;

    @Autowired
    @Qualifier("restTemplateB")
    private RestTemplate restTemplateB;

    @Override
    public void test() {
        restTemplateA.delete("uri");
        restTemplateB.delete("uri");
    }
}

尝试编写测试类

我们假设对于有相同属性的类来说,Mockito会先根据类型匹配,然后根据属性名称匹配,也就是说,我们在mock的时候声明不同的属性名称即可:

@RunWith(MockitoJUnitRunner.class)
public class TestServiceTest1 {

    @InjectMocks
    private TestServiceImpl testService;

    @Mock
    private RestTemplate restTemplateA;

    @Mock
    private RestTemplate restTemplateB;

    @Test
    public void test() {
        testService.test();
    }

}

正常情况下是可以测试通过的,分别对两个RestTemplate Mock也不会有问题:

@RunWith(MockitoJUnitRunner.class)
public class TestServiceTest1 {

    @InjectMocks
    private TestServiceImpl testService;

    @Mock
    private RestTemplate restTemplateA;

    @Mock
    private RestTemplate restTemplateB;

    @Test
    public void test() {
        Mockito.doAnswer(invocation -> {
            System.out.println("a");
            return null;
        }).when(restTemplateA).delete(Mockito.anyString());
        Mockito.doAnswer(invocation -> {
            System.out.println("b");
            return null;
        }).when(restTemplateB).delete(Mockito.anyString());
        testService.test();
    }

}

但当某些特殊场景,比如父类中有相同类型的属性,或者相同类型的属性,无论如何都有一个被调用是报空指针,可以尝试如下方式:

@RunWith(MockitoJUnitRunner.class)
public class TestServiceTest1 {

    @InjectMocks
    private TestServiceImpl testService;

    @Mock(name = "restTemplateA")
    private RestTemplate restTemplateA;

    @Mock(name = "restTemplateB")
    private RestTemplate restTemplateB;

    @Test
    public void test() {
        Mockito.doAnswer(invocation -> {
            System.out.println("b");
            return null;
        }).when(restTemplateA).delete(Mockito.anyString());
        Mockito.doAnswer(invocation -> {
            System.out.println("a");
            return null;
        }).when(restTemplateB).delete(Mockito.anyString());
        testService.test();
    }

}

使用@Mock注解并指定name属性,其中name为被测对象的属性名称。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中,如果要使用 Mockitomock 同一个对象属性中嵌套相同对象多次,可以使用 `Answer` 接口来设置不同的返回值。具体来说,可以针对每个需要 mock对象设置一个返回值列表,然后在 `Answer` 的 `answer` 方法中使用这些列表来模拟多次调用返回不同的值。 举个例子,假设有以下的类和对象: ```java public class User { private String name; private int age; public User(String name, int age) { this.name = name; this.age = age; } // getter and setter methods } public class Group { private String name; private List<User> users; public Group(String name, List<User> users) { this.name = name; this.users = users; } // getter and setter methods } User user1 = new User("Alice", 20); User user2 = new User("Bob", 25); List<User> users = new ArrayList<User>(); users.add(user1); users.add(user2); Group group = new Group("Group1", users); ``` 那么在单元测试中,可以这样 mock 对象属性中嵌套相同对象多次: ```java import static org.mockito.Mockito.*; public class TestMockito { @Test public void testMockNestedObjects() { User userMock1 = mock(User.class); User userMock2 = mock(User.class); Group groupMock = mock(Group.class); when(userMock1.getName()).thenReturn("AliceMock1"); when(userMock2.getName()).thenReturn("BobMock1"); when(groupMock.getName()).thenReturn("GroupMock1"); when(userMock1.getAge()).thenReturn(21); when(userMock2.getAge()).thenReturn(26); List<List<User>> usersList = new ArrayList<List<User>>(); usersList.add(Arrays.asList(userMock1, userMock2)); usersList.add(Arrays.asList(userMock2, userMock1)); when(groupMock.getUsers()).thenAnswer(new Answer<List<List<User>>>() { private int count = 0; @Override public List<List<User>> answer(InvocationOnMock invocation) throws Throwable { return usersList.get(count++); } }); assertEquals("AliceMock1", userMock1.getName()); assertEquals("BobMock1", userMock2.getName()); assertEquals("GroupMock1", groupMock.getName()); assertEquals(users, groupMock.getUsers()); when(userMock1.getName()).thenReturn("AliceMock2"); when(userMock2.getName()).thenReturn("BobMock2"); when(groupMock.getName()).thenReturn("GroupMock2"); assertEquals("AliceMock2", userMock1.getName()); assertEquals("BobMock2", userMock2.getName()); assertEquals("GroupMock2", groupMock.getName()); assertEquals(users, groupMock.getUsers()); } } ``` 在上面的测试函数中,我们使用 `mock` 函数创建了需要 mock对象,然后分别设置了它们的属性和返回值列表。在 `when` 中,我们使用了这些返回值列表来模拟多次调用返回不同的值。在 `groupMock.getUsers()` 中,我们使用了 `Answer` 接口来模拟多次调用返回不同的值。最后在测试中,我们分别测试了每次调用返回的值是否正确。 需要注意的是,在使用 `Answer` 接口时,我们需要在 `answer` 方法中记录当前调用的次数,并从返回值列表中取出相应的值返回,这样才能模拟多次调用返回不同的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值