How to mock Vertx.io async handler to return different asyncResult for different JsonObject as a parameter for mongoClient methods.
I have tried by pass Mockito.any() as a parameter in doAnswer()
Mockito.when(asyncResult.result()).thenReturn(result);
Mockito.doAnswer(new Answer<AsyncResult<JsonObject>>()
{
#Override
public AsyncResult<JsonObject> answer(InvocationOnMock arg0) throws Throwable {
((Handler<AsyncResult<JsonObject>>) arg0.getArgument(3)).handle(asyncResult);
return null;
}
}).when(mongo).findOne(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
I have 2 different results in for 2 different query so for one result I have mocked as above , but for another gives different result for different JsonObject. So how to mock same method with different result in same function.
Related
In my Junit Jupiter API 5.5 test, I am calling my method which internally makes a HTTP call to a remote service.
Now the remote service can be down or behave incorrectly. I want to skip my test in case the remote service is not behaving expectedly.
#Test
void testMe() {
// do something
Result res1 = myObject.retrieveResults(params)
// assert something
Result res2 = myObject.retrieveResults(param2)
//asert on results
}
Result retrieveResults(Parameters param) {
// do something
// call to remote service
// if they do not give result throw CustomException()
// return Result
}
So basically in my test i would want to check if myObject.retrieveResult is throwing CustomException then skip that test, otherwise evaluate normally.
We have 2 different ways to accomplish this tasks in JUnit 5.
For demo purposes, I have created a basic class which sends a request to the url
that is passed as an argument to its call(String url) method and
returns true or false depending on the request result.
The body of the method is irrelevant here.
Using Assumptions.assumeTrue()/assumeFalse() methods
Assumptions class provides us with two overloaded methods - assumeTrue
and assumeFalse. The idea is that, if the assumption is wrong, the test will be skipped.
So, the test will be something like this.
#Test
void call1() {
Assumptions.assumeTrue(new EndpointChecker(), "Endpoint is not available");
Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
Here is the code for EndpointChecker class.
static class EndpointChecker implements BooleanSupplier {
#Override
public boolean getAsBoolean() {
// check the endpoint here and return either true or false
return false;
}
}
When the test is run, the availability of the endpoint will be checked first, if it is up, then the test will run.
Using JUnit 5 extension mechanisms.
So, let's start with creating the annotation. It is pretty straightforward.
#Retention(RetentionPolicy.RUNTIME)
#ExtendWith(EndpointAvailabilityCondition.class)
public #interface SkipWhenEndpointUnavailable {
String uri();
}
And EndpointAvailabilityCondition class. Even though, it looks big, overall logic is very simple.
import static org.junit.platform.commons.util.AnnotationUtils.findAnnotation;
public class EndpointAvailabilityCondition implements ExecutionCondition {
#Override
public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
final var optional = findAnnotation(context.getElement(), SkipWhenEndpointUnavailable.class);
if (optional.isPresent()) {
final SkipWhenEndpointUnavailable annotation = optional.get();
final String uri = annotation.uri();
// check connection here start
boolean result = false; // dummy value
// check connection here end
if (result) {
return ConditionEvaluationResult.enabled("Connection is up");
} else {
return ConditionEvaluationResult.disabled("Connection is down");
}
}
return ConditionEvaluationResult.enabled("No assumptions, moving on...");
}
}
Hence, we can do the following in our tests.
#Test
#SkipWhenEndpointUnavailable(uri = "https://www.google.com")
void call2() {
Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
We can go ahead and add #Test annotation over #SkipWhenEndpointUnavailable and remove it from our test code. Like, so:
#Retention(RetentionPolicy.RUNTIME)
#ExtendWith(EndpointAvailabilityCondition.class)
#Test
public #interface SkipWhenEndpointUnavailable {
String uri();
}
class HttpCallerTest {
#SkipWhenEndpointUnavailable(uri = "https://www.google.com")
void call2() {
Assertions.assertTrue(HttpCaller.call("https://www.google.com"));
}
}
I hope it helps.
I am new to Mockito and Powermockito. I have a class to test which interacts with the database in order find and also delete data from the database through different public methods. The application is typical Java EE application and the The class under test belongs to Service package in Businesslogic. The method which I want to test looks like below :
public List<QuestionDtoWrapper> searchInQuestions(final Integer ID, final Integer catID,
final String searchString, final String language) {
final List<QuestionDtoWrapper> result = new ArrayList<>();
//In line below I get null pointer exception although I have stubbed this method
final List<QuestionDtoInt> questions = facade.findQuestionsByCatTemplate(ID, catID,
searchString, language);
for (final QuestionDtoInt question : questions) {
result.add(new QuestionDtoWrapper(question));
}
Collections.sort(result, new QuestionComparator(new Locale("de")));
return result;
}
This is how I tried to test the method in my Junit Test:
#RunWith(MockitoJUnitRunner.class)
#PrepareForTest(QuesService.class)
public class QuesServiceTest {
#Mock
QuesFacade mockFbFacade;
#Mock
List<QuesDtoInt> questions;
#Spy
QuesService myService = new QuesService();
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void testSearchInQuestions() throws ParseException {
PowerMockito.doReturn(questions).when(mockFbFacade).findQuestionsByCatTemplate(anyInt(), anyInt(), anyString(), anyString());
List<QuestionDtoWrapper> res = null ;
res = myService.searchInQuestions(anyInt(), anyInt(), anyString(), anyString());
assertNotNull(res);
}
I am getting Null pointer exception in Line where the method calls another method. See my comment in source code. Could someone please let me know:
1) Am I using mockito for the correct subject ? Should I use real Test data ? But what about the database connections n all ? I tried that approach and ended up using Mockito only.
2) Why am I getting Null pointer exception although I have stubbed that method with Powermockito ?
3) please provide your valuable suggestions to test the given method correctly.
Note:- I am not allowed to do any refactoring in the code.
Written my Junit test case as below. Getting some no such method error when i run my testcases.
ResponseObject res = initialized with some data;
ServiceImpl servie;
#Test
public void methidName(){
ResponseObject mockObject= Mockito.spy(new ResponseObject(data));
mockObject.setters() // more setters follows
doReturn(someretunObject).when(mockObject).somethod();
// calling actual method here now
service.transfor();
}
Actual Classes
ResponseOject {
List<JSONObject> jsonList;
......
}
ServiceImpl{
public SearchResponse transfor(SearchResponse response) {
JSONObject obj= new JSONObject(response.getConent());
JSONArray arr= (JSONArray) obj.get("RootNode");
ArrayList<JSONObject> list=new ArrayList<>();
for(int i=0i<arr.size();i++){
list.add(arr.get(i));
}
// doing some sorting here with the list
Collections.sort(list, comparator);
/**/ setting the sorted collection to response object as below**
response.setJsonList(list);
JSONObject obj= new JSONObject();
obj.put("rootNode", response.getJsonList);
// getting error in above line during Junit testcase run
}
}
Problem Statement
Getting error at this point in actual method
obj.put("rootNode", response.getJsonList);
java.lang.NoSuchMethodError: org.json.JSONObject.put(Llava/lang/String;Ljava/lanf/
Collection;)Lorg/json/JSONObject
Any reason why it so. Am i missing something?
Are you calling the method you think you are? Your test is invoking this method:
service.transfor()
but your code example shows this method:
public SearchResponse transfor(SearchResponse response)
The one you showed takes an input parameter, but you aren't passing one, so it appears you are not invoking the method you intend to be testing. If this is just a mistake in what you posted, then you should look at what object you have mocked to be returned by the response.getJsonList call. If it is returning an object that is of a type that is different from the type required by the obj.put method then you could get this error.
I need to know how can I mock a method which uses .collect(java 8) method, below is the method
//return data
public String getData(List<Node> nodes)
{
return nodes.stream().map(node->
getService().compare(new Reference()).collect(Collectors.joining(~));
}
protected getService()
{
return service;
}
I can mock service like
#Mock //mocking service
Service service
now how can I mock
getService().compare(new Reference()).collect(Collectors.joining(~));
Compare method returns CompareRef object. I can use PowerMock.
In your case I would recommend to mock the compare() method, not collect().
Because you work with a stream you may have some nodes. To emulate the behaviour with multiply call of compare() with the same Reference object you may try this variant:
final CompareRef expectedCompareRef1 = new CompareRef();
final CompareRef expectedCompareRef2 = new CompareRef();
final CompareRef expectedCompareRef3 = new CompareRef();
when(service.compare(eq(new Reference())).thenReturn(expectedCompareRef1).thenReturn(expectedCompareRef2).thenReturn(expectedCompareRef3);
then call you getData() method:
final List<Nodes> givenNodes = new ArrayList<>();
givenNodes.add(node1);
givenNodes.add(node2);
givenNodes.add(node3);
final String actualResult = myInstance.getData(givenNodes);
Assert.assertEquals("TODO: expectedResult", actualResult);
As result the stream will collect all your test expectedCompareRefN objects.
Note, to have working eq(new Reference()) your Reference class should implement equals/hashCode methods. Otherwise eq(new Reference()) always be false and thenReturn will not return the specified expected objects.
The tested method has the following code:
SuppressWarnings suppressWarnings = method.getAnnotation(SuppressWarnings.class);
In my test method.I mocked java.lang.reflect.Method:
Method method= PowerMock.createMock(Method.class);
SuppressWarnings sw = EasyMock.createMock(SuppressWarnings.class);
EasyMock.expect(method.getAnnotation(SuppressWarnings.class)).andReturn(sw);
In the tested method,
method.getAnnotation(SuppressWarnings.class); always returns null.
I don't know why.Could anyone help me?
//code:
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public #interface Anonymous {
}
public class AnnotationClass {
public Anonymous fun(Method m){
Anonymous anonymous = m.getAnnotation(Anonymous.class);
return anonymous;
}
}
// test class:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Method.class)
public class AnnotationClassTest {
#Test
public void test() throws NoSuchMethodException, SecurityException {
AnnotationClass testClass = new AnnotationClass();
final Method mockMethod = PowerMock.createMock(Method.class);
final Anonymous mockAnot = EasyMock.createMock(Anonymous.class);
EasyMock.expect(mockMethod.getAnnotation(Anonymous.class)).andReturn(mockAnot);
PowerMock.replay(mockMethod);
final Anonymous act = testClass.fun(mockMethod);
Assert.assertEquals(mockAnot, act);
PowerMock.verify(mockMethod);
}
}
error:
java.lang.AssertionError: expected:<EasyMock for interface
com.unittest.easymock.start.Anonymous> but was:<null>
SuppressWarnings has #Retention(value=SOURCE) which means that it is not available at runtime:
public static final RetentionPolicy SOURCE: Annotations are to be discarded by the compiler.
However, if you would try your code with a different annotation that is available at runtime, method.getAnnotation(MyAnnotation.class) would still return null. That is, because by default the mocked Method will return null for method calls.
I think your problem is in the configuration of the mock, when I run your code (using an annotation that is available at runtime) I get the following exception:
Exception in thread "main" java.lang.IllegalStateException: no last call on a mock available
at org.easymock.EasyMock.getControlForLastCall(EasyMock.java:466)
at org.easymock.EasyMock.expect(EasyMock.java:444)
at MockStuff.main(MockStuff.java:54)
This page has some explanations about how to mock a final class (such as Method).
Your code gives the exact same result for me. I was able to get it working using the following code:
#RunWith(PowerMockRunner.class)
#PrepareForTest(Method.class)
public class AnnotationClassTest {
#Test
public void test() throws NoSuchMethodException, SecurityException {
final Method mockMethod = PowerMock.createMock(Method.class);
final Anot mockAnot = EasyMock.createMock(Anot.class);
EasyMock.expect(mockMethod.getAnnotation(Anot.class)).andReturn(mockAnot);
PowerMock.replay(mockMethod);
final Anot methodReturn = mockMethod.getAnnotation(Anot.class);
Assert.assertEquals(mockAnot, methodReturn);
}
}
#Retention(RetentionPolicy.RUNTIME)
#interface Anot {}
Note that this code is self contained, I defined the Anot interface since you didn't give the definition of Anonymous.