I have a method that will call a service with a Callable implementation. However, I have no idea how to mock this implementation in my test code because the Callable is implemented with lambda expression on the fly. Is there any way i can achieve this?
protected Foo (){
final Callable<MyResponse> myTask = () -> {
MyRequest myRequest = new MyRequest();
Mycliet.call(myRequest);
}
Future<MyResponse> myResponse = executor.submit(myTask);
}
}
No you can't (without doing terrible reflection hacks). A mock must be injected in some way.
So you will need to refactor.
Related
How to mock listAPiMetrics when my code looks like this
List<JSONObject> metrics = new ApiMetricsClient().listApiMetrics(new ApiIdList(apiIds));
You can not mock that behavior. Because you are initiate your object inside code. You need to inject dependencies via contrutor or somehow. Basically, you need to do dependency injection.
Some mock frameworks (like moq from c#) able to mock only interface or abstract types so you need to inject your dependencies as interface which this is the most common way in general. Some frameworks like mockito/powermock allow to mock concrete types too (powermock also can be able to mock private methods as I remember).
Change your code to work as below :
class YourClass {
private IApiMetricsClient apiMetricClient;
public YourClass(IApiMetricsClient apiMetricClient) {
this.apiMetricClient = apiMetricClient;
}
public [returnType] yourMethod() {
List<JSONObject> metrics = this.apiMetricClient.listApiMetrics(new ApiIdList(apiIds));
// other logics and return data or whatever
}
}
I am using Mockito to write a simple unit test.
I have a function to test:
public void doSomething() {
foo.getStudent(new School());
}
My test case:
#Test
public void testDoSomething() {
Foo mockedFoo = Mockito.mock(Foo.class);
School mockedSchool = Mockito.mock(School.class);
// I want to pass the mocked school as parameter when food.getStudent(school) is called
// how to pass mocked school to method?
when(mockedFoo.getStudent(???))
// run the method under test
myService.doSomething();
}
I want to pass the mockedSchool as parameter when foo.getStudent(school) is called, how to declare this in Mockito?
Seems Mockito only has when(...).thenReturn(), but is there something like when(...).thenPassArgument(mockedObject) ?
The problem lies in the way you instantiate the School class in the doSomething method; as you instantiate it on the spot you can't overload that instantiation with the mock using mockito.
If you pass it as a parameter of doSomething you should be able to perform this.
I believe PowerMock can help you if you want to overload an internal construction.
As you don't need to assert into the School instance and just pass a mocked instance as a parameter, you can do the following:
mockedBar.getStudent(Mockito.isA(School.class));
Please read the Mockito documentation about the isA(java.lang.Class<T> clazz) method.
I am testing out Grails static compilation, specifically GrailsCompileStatic. The documentation is limited in explaining what Grails dynamic features aren't supported. My test Controller is very simple, but I'm running into problems already.
#GrailsCompileStatic
class UserController {
UserService userService
def list() {
def model = [:]
def model = request.JSON
withFormat {
json {
render(model as JSON)
}
}
}
}
When compiling the application I get two compile time errors. The first about a missing property for JSON on the request object, and a second error about a missing method for json in the withFormat closure.
Seems to me I'm either doing something wrong or GrailsCompileStatic doesn't work with these features?
About request.JSON
The request object's getJSON() method is added via the ConvertersPluginSupport class. The exact lines are:
private static void enhanceRequest() {
// Methods for Reading JSON/XML from Requests
def getXMLMethod = { -> XML.parse((HttpServletRequest) delegate) }
def getJSONMethod = { -> JSON.parse((HttpServletRequest) delegate)}
def requestMc = GrailsMetaClassUtils.getExpandoMetaClass(HttpServletRequest)
requestMc.getXML = getXMLMethod
requestMc.getJSON = getJSONMethod
}
As you can see it uses the dynamic dispatch mechanism, but fortunately it's not such a big deal. You can simply replicate it by executing JSON.parse(request) anywhere in your controller.
Pay attention though! JSON.parse(HttpServletRequest) returns an Object, which is either a JSONObject or a JSONArray, so if you plan on using them explicitly, and you are compiling statically, you will have to cast it.
You might create a common base class for your controllers:
import org.codehaus.groovy.grails.web.json.JSONArray
import org.codehaus.groovy.grails.web.json.JSONObject
import grails.converters.JSON
#GrailsCompileStatic
class BaseController {
protected JSONObject getJSONObject() {
(JSONObject) JSON.parse(request)
}
protected JSONArray getJSONArray() {
(JSONArray) JSON.parse(request)
}
}
Then in your controller you can simpy invoke getJSONObject() or getJSONArray. It's a bit of a workaround, but results in a staticly compileable code.
About withFormat
This is a bit more complicated. The withFormat construct is really a method, which has a Closure as it's first parameter. The internal implementation then figures out based on the current request or response content type which part of the argument closure is to be used.
If you want to figure out how to do this statically, take a look at the source code.
You could extend this class, then use it's protected methods, but I don't know if it's worth all the hussle, you would loose much of Grails' conciseness. But if you really want to do it, you can. Don't you just love open source projects ? :)
I use Jersey and I have the following Rest function which returns a JSON string when my server is deployed:
#GET
#Path("getallemployees")
#Produces("application/json")
public Response getAllEmployees() {
//building the entity object which is List<Employee>
return Response.ok(entity).build();
}
I need to develop some unit tests (not integration testing) and I want to somehow mock the HTTPRequest that invokes this method and then get the json String. The best option would be to use mockito for this.
Is there any suggestion on how to do it ?
Thanks !!
The problem is that the method returns a Response object to the caller which is deep within the framework code. It doesn't return JSON strings.
You can use Mockito, if you need to mock something inside the method itself. That should work.
But you may need to take the value returned by the method and convert it to JSON like this if you are using Jackson with Jersey.
Response response = getAllEmployees();
Object retval = response.getEntity();
try {
ObjectMapper mapper = new ObjectMapper();
// I like this formatting. You can change it.
mapper.configure(Feature.INDENT_OUTPUT, true);
mapper.configure(Feature.WRITE_ENUMS_USING_TO_STRING, true);
mapper.configure(Feature.USE_ANNOTATIONS, false);
mapper.configure(Feature.FAIL_ON_EMPTY_BEANS, false);
mapper.setSerializationInclusion(Inclusion.NON_NULL);
mapper.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
mapper.getSerializationConfig().withSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
String json = mapper.writeValueAsString(retval);
... assert something about the string
} catch (JsonProcessingException e) {
// do something
} catch (IOException e) {
// do something
}
Some of this is guess work and speculation on my part but it may help. You could try using the Jersey Test Framework with the InMemoryTestContainerFactory:
It starts Jersey application and directly calls internal APIs to handle request created by client provided by test framework. There is no network communication involved. This containers does not support servlet and other container dependent features, but it is a perfect choice for simple unit tests.
It looks like to use it, all you need to do is extend JerseyTest and then override getTestContainerFactory() and follow the rest of the instructions, e.g.:
public class EmployeeResourceTest extends JerseyTest {
#Override
protected Application configure() {
// set up employee resource with mock dependencies etc...
return new ResourceConfig().registerInstances(employeeResource);
}
#Test
public void getAllEmployees() {
final String response = target("getallemployees").request().get(String.class);
// assert etc...
}
}
I used registerInstances instead of registerClasses in configure() as it looks like you can present a ready made Resource but set up with any mock dependencies you may want - although I haven't tried this myself.
The test class is a bit inflexible as you can only do one-time set up of dependencies in the configure() method, so it might be worth investigating using the MockitoJUnitRunner - although I'm not sure if it will work with the JerseyTest inheritance. It could allow you to do add behaviour to mocks in each #Test method, e.g.:
#Mock
private EmployeeResourceDependency dependency;
#InjectMocks
private EmployeeResource employeeResource;
// configure() as above but without mock setup up etc...
#Test
public void getAllEmployees() {
given(dependency.getEmployees()).willReturn(...);
// etc...
But like I said it might not be possible to mix them at all.
How to mock Runnable here using PowerMock.... here initialize () calls some two other methods.
Can you please clarify how this can be done? searched for almost 2days..
Please try these steps:
Use the #RunWith(PowerMockRunner.class) annotation at the class-level of the test case.
Use the #PrepareForTest(ClassThatCreatesTheNewInstance.class) annotation at the class-level of the test case.
Use PowerMock.createMock(NewInstanceClass.class) to create a mock object of the class that should be constructed (let's call it mockObject).
Use PowerMock.expectNew(NewInstanceClass.class).andReturn(mockObject) to expect a new construction of an object of type NewInstanceClass.class but instead return the mock object.
Use PowerMock.replay(mockObject, NewInstanceClass.class) to change the mock object and class to replay mode, alternatively use the PowerMock.replayAll() method.
Use PowerMock.verify(mockObject, NewInstanceClass.class) to change the mock object and class to verify mode, alternatively use the PowerMock.verifyAll() method.
Reference: https://code.google.com/p/powermock/wiki/MockConstructor