0

I have a RESTeasy service I would like to test against a running server (in this case I don't want to use the mock framework from RESTeasy.

However, I would like to validate the service without the need to create "real" data so I would like to mock some of the classes which are are returning the data to the service. I basically want to validate the existence of the service and validate the uri is legit.

The problem is that I am returning a 404 in cases where data doesn't exist and have no way from the test of differentiating between a 404 of an invalid uri or a 404 from an id not found. My 404's are not returning any data. For example both of these will yield the same result to the caller:

So I want to mock my getObject(String id) method to return me a valid object and move on.

I am able to use mocks if I call the service class directly, however if I call the service via an http call, the mocks don't get used (the "real" classes are used instead).

For example something sort of like this (using jmockit)...

@Test
public void someTestMethod(@Mocked final DependencyAbc abc)
{
    // mock will get called in this case
    // doSomething uses DependencyAbc
    new RestClass().doSomething();  
    ...

    // "real DependencyAbc" gets called, not the mock.
    response = httpClient.get("http://validuri/123");
}

RESTeasy class i'm trying to test:

@GET
@Path("/validuri/{id}")
public Response doSomething(@PathParm("id") String id) {
    ...
    myObject = dependencyAbc.getObject(id);
    ...
    if (myObject == null) {
        //return 404
    }
}

I have a couple other options I can use such as use the resteasy mock framework, or return some data with 404 (currently no data is returned). However I would like to understand why the mocks are not getting called via the http calls and if there is a way to get the mocks to be called?

  • Isn't it the case that, when calling `httpClient.get(...)`, the actual service in the running server gets executed? If so, then it will use an unmocked `DependencyAbc`, since all mocking occurs inside the client JVM only. – Rogério Aug 09 '15 at 14:37

1 Answers1

0

You could create an interface for the object you want to mock containing the methods you want executed.

public interface Dependency {
    public Object getObject(String id);
}

Then you can make the class to use in your rest API that implements that interface in your mainspace

public class DependencyAbc implements dependency {
    @Override
    public Object getObject(String id) {
        //...return object
    }
}

Then in your rest API, inject the interface using CDI and the implementation will be injected polymorphically

@Inject
Dependency dependency

@GET
@Path("/validuri/{id}")
public Response doSomething(@PathParm("id") String id) {
    ...
    myObject = dependency.getObject(id);
    ...
    if (myObject == null) {
       //return 404
    }
}

Then in your tests you can create your mock dependency that implements the interface like before

public class MockDependency implements Dependency {
    @Override
    public Object getObject(String id) {
        //return good object
    } 
}

Only now, when you are building your deployment with shrinkwrap, use addClass to add the MockDependency and not the real Dependency implementation. The MockDependency will be injected polymorphically.

Weston Jones
  • 151
  • 4