I am testing my Java code using EasyMock.
The piece of code that I want to mock looks like this:
requestInfo = mupClient.newEnqueueRequestCall().call(requestArgs);
The way I am mocking this is:
expect(mupClient.newEnqueueRequestCall()).andReturn(enqueueRequestCall);
final Capture<EnqueueRequestArgs> captureRequestArgs =
new Capture<EnqueueRequestArgs>();
expect(mupClient.newEnqueueRequestCall().call(capture(captureRequestArgs))).
andThrow(new MUPCoralException("an exception"));
But requestInfo is always null. Even if I change the .andThrow() part to .andReturn(new RequestInfo()), it is still null.
I checked the other similar post but that did not work. Now was I able to comment on it and hence creating a new question.
ANSWER:
add all mock'd objects in replay! Example replay(mockObj1, mockObj2, ...)
Try this:
expect(mupClient.newEnqueueRequestCall()).andReturn(enqueueRequestCall);
final Capture<EnqueueRequestArgs> captureRequestArgs =
new Capture<EnqueueRequestArgs>();
expect(enqueueRequestCall.call(capture(captureRequestArgs))).
andThrow(new MUPCoralException("an exception"));
The problem is that your enqueRequestCall should return requestInfo. mupClient will return enqueueRequestCall only after you call replay method from easymock.
Related
I have this Method that throws an IllegalArgumentException when somebody tries to call it with value 0.
I want to write several stub and mock tests - for example - for the method getFrequentRenterPoints.
I coudn't figure out any "when" or "verify" statements which are used in mocks so I mixed parts of mocks and parts of stubs together and came up with this:
#Test
public void methodGetFrequentRenterPointsShouldThrowIllegalArgumentException() {
//given
Movie movieMock = mock(Movie.class);
//when
movieMock.getFrequentRenterPoints(0);
//then
assertThrows(IllegalArgumentException.class, () -> {
movieMock.getFrequentRenterPoints(0);
});
}
Is it okay to have in a class with other Mocks, or if I want to use assertThrows should I change this into a stub? Or can I use assertThrows with mocks?
The answer from Benjamin Eckardt is correct.
But I try to approach this question from another point of view: when to use mocking? This is one of my favourite answers to that question.
So in practise:
Say your code is like (just guessing all the business objects & names...):
List<RenterPoints> getFrequentRenterPoints(int renterId) {
if(p <= 0) {
throw new IllegalArgumentException();
}
// this is just the rest of code in which your test does not enter because
// of thrown exception
return somethingToReturn();
}
For this you do not need and you should not want to mock anything here.
But when things get more complicated like your method would be like:
List<RenterPoints> getFrequentRenterPoints(int renterId) {
if(p <= 0) {
throw new IllegalArgumentException();
}
// What is this?
// It is injected in the Movie - say - like
//
// #Resource
// private RenterPointService renterPointService;
List<RenterPoints> unfiltered = renterPointService.getRenterPoints(renterId);
return filterToFrequent(unfiltered);
}
Now if you test renterId >= 1 what about this renterPointService how do you instantiate it to not get NPE? Say if it is injected and requires to pull up heavy framework for testing or it requires very heavy construction or so? You do not, you mock it.
You are testing the class Movie not the class RenterPointService so you should not bother to think how RenterPointService works but what it returns when used in the class Movie. Still: you do not mock the class Movie which you are testing.
Assuming using you are using Mockito and using annotations the mocking would be then done in your test class like:
#Mock
private RenterPointService renterPointService;
#InjectMocks
private Movie movie;
Then you would do mocking of methods for renterPointService like:
when(renterPointService.getRenterPoints(anyInt))
.thenReturn(someListContaineingMockRenterPointsForThisTest);
Usually you expect the tested production method to throw and not the mock or stub. I drafted it by using new Movie().
Furthermore in that case it does not really make sense to separate the calls into when and then because if movieMock.getFrequentRenterPoints(0); throws, assertThrows(...) will never be executed.
To apply the given/when/then structure with the assertThrows API you could extract the passed lambda in some way, but I personally don't see much benefit in it.
#Test
public void methodGetFrequentRenterPointsShouldThrowIllegalArgumentException() {
// given
Movie movieMock = new Movie();
// when/then
assertThrows(IllegalArgumentException.class, () -> {
movieMock.getFrequentRenterPoints(0);
});
}
I'm making a test for a service with a mock.
The problem is to create and inject instance directly from the class to test.
The source is shown below.
public OrderOutDTO createOrder(OrderSessionDTO orderSessionDTO) {
Order order = orderRepository.save(new Order(orderSessionDTO));
CreateOrderResDTO callServiceOrder = callService.createOrder(new CreateOrderReqDTO(order));
CreateOrderReqDTO createOrderReqDTO = mock(CreateOrderReqDTO.class);
createTrace(order, callServiceOrder.getData().getReceipt().getTransactionHash(), Trace.PUBLIC);
return new OrderOutDTO(order, null);
}
and test source is shown below.
#Test
public void createOrder() {
// given
CallService callService = mock(CallService.class);
CreateOrderResDataDTO createOrderResDataDTO = mock(CreateOrderResDataDTO.class);
// when
when(callService.createOrder(createOrderReqDTO)).thenReturn(createOrderResDTO);
OrderOutDTO order = orderService.createOrder(orderSessionDTO);
// then
assertThat(order, is(Matchers.notNullValue()));
assertThat(order.getOrder(), is(Matchers.notNullValue()));
assertThat(order.getOrder().getReceiver().getName(), is("test"));
}
I thought this test would finish well. But in the code below, it returned null and failed.
// callService.createOrder(new CreateOrderReqDTO(order)) return null
CreateOrderResDTO callServiceOrder = callService.createOrder(new CreateOrderReqDTO(order));
It doesn't seem to recognize it because the service injects a new instance. I want the mock data returned. What should I do?
In the following line you're mocking behavior on createOrderReqDTO as param:
when(callService.createOrder(createOrderReqDTO)).thenReturn(createOrderResDTO);
whereas further, you're passing some other object:
OrderOutDTO order = orderService.createOrder(orderSessionDTO);
This behavior is not recognized, you would have to pass the same thing you mocked before.
I found it myself!
I use argumentMatchers.
when(callService.createOrder(createOrderReqDTO)).thenReturn(createOrderResDTO);
to
when(callService.createOrder(any())).thenReturn(createOrderResDTO);
thank you.
I am writing test case for a protected method, the method is called
protected boolean printMultipleImages(int rows, int cols, IIOImage[] imgs,
PrintMode mode, AutomaticCroppingOption crop,
double reduction, int renderOption)
Within this method an array variable is getting initialized, the following piece of code shows how
RenderRequest request = this.formSlotsRenderRequest(rows, cols, imgs,mode, crop, reduction);
// Create a Printer Properties Object...
PrinterProperties prop = this.getAutoPrinterProperties();
// Get the Appropriate Print Rendering Engine..
MultiFilmPrintRenderer engine = this.getPrintRenderer();
MultiFilmRenderRequest multiFilmRenderRequest = new MultiFilmRenderRequest(renderOption, request,new ChoppingPreferences());
assert engine != null;
RenderedImage[] rImageArr =engine.renderAcrossFilms(multiFilmRenderRequest, prop); //NPE here, rImageArr=null, though I mocked the method to return something.
in line highlighted below, the variable rImageArr is not getting initialized and is holding null,
the method call engine.renderAcrossFilms(multiFilmRenderRequest, prop); is giving me null even when I mock it to return something and the control is going inside the method and giving Null Pointer Exception, which should not happen since I am mocking it. All the variabales used here are local to the method.
RenderedImage[] rImageArr =engine.renderAcrossFilms(multiFilmRenderRequest, prop);
This is how I mocked the method engine.renderAcrossFilms(multiFilmRenderRequest, prop);
#Test
public void testPrintMultipleImages() throws Exception
{
//MultiFilmRenderRequest req=Mockito.mock(MultiFilmRenderRequest.class);
MultiFilmPrintRenderer engine=Whitebox.getInternalState(autoPrintEndPoint, "_engine");//new JCPrintRenderEngine();//
System.out.println(engine+"here");
RenderedImage[] renderAcrossFilms=new RenderedImage[]{Mockito.mock(RenderedImage.class)};
PrinterProperties prop=Mockito.mock(PrinterProperties.class);
RenderRequest renderRequest=Mockito.mock(RenderRequest.class);
AutomaticCroppingOption crop=Mockito.mock(AutomaticCroppingOption.class);
PrintMode mode=Mockito.mock(PrintMode.class);
IIOImage img=Mockito.mock(IIOImage.class);
MultiFilmRenderRequest multiFilmRenderRequest = new MultiFilmRenderRequest(1, renderRequest,
new ChoppingPreferences());
PowerMockito.doNothing().when(autoPrintEndPoint,PowerMockito.method(AutoPrintEndPoint.class,"loadImage", IIOImage.class)).withArguments(img);
PowerMockito.doReturn(renderRequest).when(autoPrintEndPoint,PowerMockito.method(AutoPrintEndPoint.class,"formSlotsRenderRequest", int.class, int.class, IIOImage[].class,PrintMode.class,AutomaticCroppingOption.class,double.class)).withArguments(2,2,new IIOImage[]{img},mode,crop,12.5);
PowerMockito.doReturn(prop).when(autoPrintEndPoint,PowerMockito.method(AutoPrintEndPoint.class,"getAutoPrinterProperties")).withNoArguments();
Mockito.when(engine.renderAcrossFilms(Mockito.any(MultiFilmRenderRequest.class),Mockito.any(PrinterProperties.class))).thenReturn(renderAcrossFilms);
Method printMultipleImages=AutoPrintEndPoint.class.getDeclaredMethod("printMultipleImages", int.class,int.class,IIOImage[].class,PrintMode.class,AutomaticCroppingOption.class,double.class,int.class);
printMultipleImages.setAccessible(true);
printMultipleImages.invoke(autoPrintEndPoint,2,2,new IIOImage[]{img},mode,crop,12.5,1);
}
I hope I am clear enough in my question, I hope you can help me
I will continue to expand this answer as you give more details but based on your latest update, you have:
MultiFilmPrintRenderer engine =
Whitebox.getInternalState(autoPrintEndPoint, "_engine");
// ...
Mockito.when(engine.renderAcrossFilms(multiFilmRenderRequest, prop))
.thenReturn(renderAcrossFilms);
So is this Whitebox.getInternalState returning a mock object or not?
within the method that you are going to test,
it creates the new instance
MultiFilmRenderRequest multiFilmRenderRequest = new MultiFilmRenderRequest(renderOption, request,new ChoppingPreferences());
and this will be used as a parameter of the mocked method.
but you might have mocked the method providing a arguments which is not equal to arguments that the printMultipleImages method pass to the engine.
other than this i can see
PrinterProperties prop=Mockito.mock(PrinterProperties.class);
but this mock class has not been used, so again the target test method might send a different PrinterProperties object.
you can use
engine.renderAcrossFilms(Mockito.any(MultiFilmRenderRequest.class),Mockito.any(PrinterProperties.class))
I created a mock on the engine object that was being used to call the method I was trying to mock and did a setInternalState.
MultiFilmPrintRenderer engine = Mockito
.mock(MultiFilmPrintRenderer.class);
Whitebox.setInternalState(autoPrintEndPoint, "_engine", engine);
This way the mock object was set. and the NPE was resolved
I got this code in my junit:
new NonStrictExpectations(mPersonEvaluator) {
{
invoke(mPersonEvaluator, "doEvaluatePerson", withAny(String.class), withAny(Integer.class), withAny(Integer.class));
result = doEvaluatePerson((String)any, (Integer)any, (Integer)any);
}
};
I want to generate the result from my private method doEvaluatePerson((String)any, (Integer)any, (Integer)any); everytime the method doEvaluatePerson is called in the business logic of mPersonEvaluator.
The invoke works fine but the result is only calculated once during the setup of the junit and that result is null.
My question is how can I declare such kind of usecase in jmockit so that the mock uses my private method?
Thank in advance
Stefan
ok I found the answer.
one possible solution is to use a Delegator like this:
result = new Delegate<PersonArt>() {
PersonArt delegator(String pShortName, Integer pOld, Integer pSize)
{
return doEvaluatePersonArt(pShortName, pOld, pSize);
}
};
works pretty fine.
This question already has answers here:
Creating a mock HttpServletRequest out of a url string?
(5 answers)
Closed 8 years ago.
I have a function that looks for a query parameter and returns a boolean:
public static Boolean getBooleanFromRequest(HttpServletRequest request, String key) {
Boolean keyValue = false;
if(request.getParameter(key) != null) {
String value = request.getParameter(key);
if(keyValue == null) {
keyValue = false;
}
else {
if(value.equalsIgnoreCase("true") || value.equalsIgnoreCase("1")) {
keyValue = true;
}
}
}
return keyValue;
}
I have both junit and easymock in my pom.xml, how do I go about mocking the HttpServletRequest ?
Use some mocking framework e.g. Mockito or JMock which comes with mocking capacity of such objects.
In Mockito, you can do mocking as:
HttpServletRequest mockedRequest = Mockito.mock(HttpServletRequest.class);
For details on Mockito, see: How do I drink it? on the Mockito site.
In JMock, you can do mocking as :
Mockery context = new Mockery();
HttpServletRequest mockedRequest = context.mock(HttpServletRequest.class);
For details on jMock, please refer: jMock - Getting Started
HttpServletRequest is much like any other interface, so you can mock it by following the EasyMock Readme
Here is an example of how to unit test your getBooleanFromRequest method
// static import allows for more concise code (createMock etc.)
import static org.easymock.EasyMock.*;
// other imports omitted
public class MyServletMock
{
#Test
public void test1()
{
// Step 1 - create the mock object
HttpServletRequest req = createMock(HttpServletRequest.class);
// Step 2 - record the expected behavior
// to test true, expect to be called with "param1" and if so return true
// Note that the method under test calls getParameter twice (really
// necessary?) so we must relax the restriction and program the mock
// to allow this call either once or twice
expect(req.getParameter("param1")).andReturn("true").times(1, 2);
// program the mock to return false for param2
expect(req.getParameter("param2")).andReturn("false").times(1, 2);
// switch the mock to replay state
replay(req);
// now run the test. The method will call getParameter twice
Boolean bool1 = getBooleanFromRequest(req, "param1");
assertTrue(bool1);
Boolean bool2 = getBooleanFromRequest(req, "param2");
assertFalse(bool2);
// call one more time to watch test fail, just to liven things up
// call was not programmed in the record phase so test blows up
getBooleanFromRequest(req, "bogus");
}
}
This is an old thread ... but the question is still relevant.
Another good choice is MockServiceRequest and MockServiceResponse in the Spring framework:
http://docs.spring.io/spring/docs/2.0.x/api/org/springframework/mock/web/package-summary.html
I don't know about easymock, but the book 'Unit Testing in Java: How Tests Drive the Code' by Johannes Link contained explanations of how to test Servlets using a library he'd build of dummy objects.
The companion site for the book is now gone (change in publishing company of something...) but the companion site from the original german publication is still up. From it, you can download the definitions of all the dummy objects.
Have a look at Mockrunner: http://mockrunner.sourceforge.net/
It has a lot of easy to use Java EE mocks, including HttpServletRequest and HttpServletResponse.