重构:创建新实例的Mockito

时间:2018-11-14 12:49:30

标签: unit-testing spring-boot mockito refactoring

我有一个类,它是某些其他应用程序的客户端。

class StarFleetClient {
    private RestTemplate restTemplate = null;
    private String accessToken = null;

    public StarFleetClient(String address, String username, String password) {
        restTemplate = new RestTemplate();
        accessToken = restTemplate.postForEntity(...);
    }

    public String attack() {
        return restTemplate.exchange(... )
    }
}

现在,每当需要时,我都会创建此类的多个实例。每次凭据将不同。

new StarFleetClient("address1", "user1", "pass");

另一些​​时间

new StarFleetClient("address1", "user1", "pass");

以此类推...

现在,这很正常,但是当我编写单元测试时出现了问题。我不想在进行测试时称呼实际的星际舰队。我需要模拟RestTemplate,但是由于正在创建新实例,因此无法正确进行模拟。

如何为此编写测试用例?或者如何使此代码可测试?

技术堆栈:Spring Boot,Mockito

2 个答案:

答案 0 :(得分:0)

您可以使用@Mock@InjectMocks批注来实现所需的功能。为了简单起见,我在代码摘录中将restTemplate.postForEntityrestTemplate.exchange方法替换为restTemplate.toString()

因此,考虑到StarFleetClient

class StarFleetClient {
    private RestTemplate restTemplate = null;
    private String accessToken = null;

    public StarFleetClient(String address, String username, String password) {
        restTemplate = new RestTemplate();
        accessToken = restTemplate.toString();
    }

    public String attack() {
        return restTemplate.toString();
    }
}

模拟RestTemplate的Mockito测试可能是:

@RunWith(MockitoJUnitRunner.class)
public class StarFleetClientTest {

    @Mock
    RestTemplate restTemplate;

    @InjectMocks
    StarFleetClient starFleetClient = new StarFleetClient("somewhere", "user", "password");

    @Test
    public void testStarFleetAttack() {
        Mockito.when(restTemplate.toString()).thenReturn("called Mocked RestTemplate");
        assertEquals("called Mocked RestTemplate", starFleetClient.attack());
    }
}

答案 1 :(得分:-1)

您需要模拟RestTemplate

 @Mock
 RestTemplate restTemplate;

并找到一种将其注入到您正在测试的类中的方法(通过setter或构造函数)。 由于您使用的是Spring,因此restTemplate可能是应用程序中的bean,并且可以用测试上下文的模拟代替。

然后使用模仿器模拟您想要的行为:

Mockito.when(restTemplate.get...)
            .thenReturn(something);