2

如何使用 EasyMock 对以下方法进行单元测试。我试图模拟 WebResource 但它返回给我一个NullPointerException.

public void connect()
{
   Client client = setUpClient();
    WebResource jobBuilder = client.resource("URL");
   String jobXml = jobBuilder.accept(MediaType.APPLICATION_XML)
                .type(MediaType.APPLICATION_JSON)
                .entity(request)
                 .post(String.class);    
}


 public Client setUpClient()
   {
            ClientConfig cc = new DefaultClientConfig();
            cc.getClasses().add(JacksonJsonProvider.class);
            Client client = Client.create(cc);
            return client;
    }
4

1 回答 1

3

You clearly have to read up on the Inversion of Control Principle (http://en.wikipedia.org/wiki/Inversion_of_control), if not for the sake of the better designed code, then for the sake of unit testing. The client object in the method above is created inside the method itself, using the static factory method Client.create(). There is no good way to inject a mock collaborator with that approach. You should either allow injection of the client via a setter or a constructor, or delegate its creation to some sort of a factory.

If you use the 1st approach, you can inject the mock client directly via the setter or constructor during the unit test setup.

If you use the 2nd approach, you can provide a factory that would return a mock client when called.

EDIT 5/03:

Here's example of making your code testable by providing an object factory for a 3rd party library object:

public class ClassToTest {

    private ClientFactory factory;

    public ClassTotest() {
        this(new ClientFactory());
    }

    public ClassToTest(ClientFactory factory) {
        this.factory = factory;
    }

    public void connect() {
        Client client = factory.getClient();
        WebResource jobBuilder = client.resource("URL");
        String jobXml = jobBuilder.accept(MediaType.APPLICATION_XML)
                    .type(MediaType.APPLICATION_JSON)
                    .entity(request)
                    .post(String.class);    
    }
}

public class ClientFactory() {
    public Client getClient() {
                ClientConfig cc = new DefaultClientConfig();
                cc.getClasses().add(JacksonJsonProvider.class);
                Client client = Client.create(cc);
                return client;
    }
}

Now, in your application code you can instantiate your class using the no-argument constructor. In the unit test you would use the other constructor. This way you would be able to inject a mock Client that you would script for the purpose of testing WebResource.

Hope this helps.

于 2013-05-03T16:00:17.547 回答