如何在下面的代码中模拟旧对象?

时间:2019-01-09 10:08:36

标签: java mockito

我一直在使用Mockito框架编写单元测试。 我在旧代码下面有这个代码,如何在不重构它的情况下,在approvalAction方法中模拟RemoteService客户端对象?

public Map<String, String> approvalAction(long documentId, ActionCommandDTO request, FormData formData, byte[] prevData) {

    RemoteService client = getRemoteService();
    String urlString = String.format("formExtensions/%s?%s", formData.getId(), getAuthParam(formData.getRealm()));
    try {
        response = client.postEntity(urlString, String.class, approvalSvcRequestStr);
    } catch (Exception e) {
        // TODO: handle rollback properly for P2P
        handleApprovalActionFailed(documentId, request, formData, prevData);
    }

    return map;
}


private RemoteService getRemoteService() {

    RemoteServiceConfig remoteServiceConfig = (RemoteServiceConfig) this.serviceConfigRegistry.getServiceConfigs().get("approval");
    remoteServiceConfig.setClientID(clientId);
    remoteServiceConfig.setClientSecret(privateSecret);
    RemoteService remoteService = new RemoteService(remoteServiceConfig, authorizationHeaderServiceImpl);

    return remoteService;
}

3 个答案:

答案 0 :(得分:1)

为什么不让RemoteService通过构造函数注入,但又允许默认构造函数?

class YourClass{

    private final RemoteService client;

    public YourClass(RemoteService client){
        this.client = client;
    }

    public YourClass(){
        RemoteServiceConfig remoteServiceConfig = (RemoteServiceConfig) this.serviceConfigRegistry.getServiceConfigs().get("approval");
        remoteServiceConfig.setClientID(clientId);
        remoteServiceConfig.setClientSecret(privateSecret);
        client = new RemoteService(remoteServiceConfig, authorizationHeaderServiceImpl);
    }

    // all of your other methods inside the class

}
  

当然,您必须调整已经存在的构造函数。但是由于您尚未显示整个课程,对我来说这是不可能的。

这使您在YourClass的整个生命周期中只有一个客户端实例。


现在很容易模拟RemoteService。只需使用模拟的客户端实例化YourClass

RemoteService mock = mock(RemoteService.class);
YourClass toTest = new YourClass(mock);

答案 1 :(得分:0)

getRemoteService更改为protected,并使用子类覆盖它:

public class SomeService {

    public Map<String, String> approvalAction(long documentId, ActionCommandDTO request, FormData formData, byte[] prevData) {

    }


    // change here
    protected RemoteService getRemoteService() {

        RemoteServiceConfig remoteServiceConfig = (RemoteServiceConfig) this.serviceConfigRegistry.getServiceConfigs()
                .get("approval");
        remoteServiceConfig.setClientID(clientId);
        remoteServiceConfig.setClientSecret(privateSecret);
        RemoteService remoteService = new RemoteService(remoteServiceConfig, authorizationHeaderServiceImpl);

        return remoteService;
    }

}


public class TestSomeService extends SomeService {


    @Override
    protected RemoteService getRemoteService() {
        return new MockService();
    }
}

答案 2 :(得分:0)

您不能模拟RemoteService,因为它是在您的类中创建的。如果可能,将getRemoteService提取到另一个类,则将其称为NewClass。现在您可以模拟NewClass。

public Map<String, String> approvalAction(long documentId, ActionCommandDTO request, FormData formData, byte[] prevData) {

    RemoteService client = NewClass.getRemoteService(params);
    ///
}

另一种方法是,如果您不想大量更改旧代码,则可以扩展您的类(该类实现rovalingAction),并覆盖getRemoteService()函数。在getRemoteService调用的新实现中,创建模拟RemoteService。您可以测试这个新课程。