junit to test a method calling webservice - junit

I am newbie to junit.
I need to do junit for the following method. kindly guide me
public boolean binlist(params hpproxy, calendarparam cpxproxy)
{
Getbinresponse binresponse;
cpproxy.setid(hpproxy.getId());
binresponse= cpproxy.getBinlist(); // resturns a list calling webservice
if (binresponse.size>0)
{
result=true;
}
else
{
result=false;
}
return result;
}
I have tried to test the binlist method using mock object.
class testbin
{
#test
public void testbinlist()
{
Testbin mocktestbin=mock(testbin.class);
calendarproxy cpproxy=mock(calendarproxy.class);
params hpproxy= mock(cparams.class);
hpproxy.setId("123");
stub(cpproxy.getBinList()).toReturn(gettestbins()) // mocked getbinlist()
boolen result= mocktestbin.binlist();
assertTrue(result);
}
}
how to test the webservice inside a method?

I think you are pretty spot on in your test. I think you do not need to mock the Testbin since that is the class under test. Just create a mock of the calendarproxy that is being passed on as an argument.
So your test method to test bin would look something like what is below.
class testbin
{
#test
public void testbinlist()
{
Testbin mocktestbin= new Testbin();
calendarproxy cpproxy=mock(calendarproxy.class);
params hpproxy= mock(cparams.class);
hpproxy.setId("123");
when(cpproxy.getBinList()).thenReturn(gettestbins()); // mocked getbinlist()
boolen result= mocktestbin.binlist(hpproxy,cpproxy);
assertTrue(result);
}
}

Related

JUnit Mockito: Testing a Static Method and Calling Another Stubbed Static Method Inside Not Working

class A {
public static int f1() {
return 1;
}
public static int f2() {
return A.f1();
}
}
class ATest {
#Test
void testF2() {
try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class)) {
aStatic.when(A::f1).thenReturn(2);
int ret = A.f2(); // getting 0 here
assertEquals(ret, 2);
} catch(Exception e) {
}
}
}
In the testF2 I want to test static function A::f2().
And it internally calls another static function A::f1().
I did stub A::f1() to return 2 using "MockedStatic" and "when" way.
But it's not working, it's returning 0.
How to solve it?
I think you miss to specify a mock behavior:
class ATest {
#Test
void testF2() {
try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class)) {
aStatic.when(A::f1).thenReturn(2);
aStatic.when(A::f2).thenReturn(A.f1()); // <- added this
int ret = A.f2(); // getting 0 here
Assertions.assertEquals(ret, 2);
} catch (Exception e) {
}
}
}
by telling the mock what to do when A.f2() is invoked, test runs fine.
Update:
Mocks do what you tell them, if you don't tell what to do when a method is invoked they do nothing, that's why you have to mock f2 too.
You want to test A, then mock it is not your friend. I normally use a Mockito.spy() to partially mock my subject under test .You want to mock f1 but test f2, I don't think spy applies here because there is no instance to spy..
I suggest you to rearrange A avoiding static methods if possible or using parameters you can mock.
When you mock a class with static methods, all static methods are mocked. If you only want to mock the behavior of only 1 method, you have to add Mockito.CALLS_REAL_METHODS argument to Mockito.mockStatic() as you can see in the following example.
#Test
void testF2() {
try (MockedStatic<A> aStatic = Mockito.mockStatic(A.class, Mockito.CALLS_REAL_METHODS)) {
aStatic.when(A::f1).thenReturn(2);
int ret = A.f2(); // getting 2 here
Assert.assertEquals(2, ret); // (expected, result)
} catch(Exception e) {
}
}
This way only the f1 method invocation is mocked but f2 invocation calls the real code.

Conditionally skip a Junit 5 test

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.

How to mock a Consumer argument using EasyMock with PowerMock

I have a test scenario where I need to mock a Consumer parameter.
In the following code the startTracer is the method to be tested.
class TracerService {
private TracerController tracerController;
public void startTracer(String tracerName, Object param1) {
if (attendStartConditions(tracerName, param1)) {
executeOnTracerControllerScope(tracerController -> tracerController.startTracer(param1));
}
}
...
}
Basically, I want to test if the tracerController.startTracer(param1) is receiving the param1 as argument.
Capture<Object> method1Param1 = newCapture();
tracerController.startTracer(capture(method1Param1));
expectLastCall().once();
...
tracerService.startTracer("TEST", "value1");
assertThat(method1Param1.getValue()).isEqualsTo("value1");
How I can configure EasyMock/PowerMock for that executeOnTracerControllerScope execute tracerController.startTracer without invocating their internal code?
tracerController is a mock. So startTracer won't be called on it. As defined right now, it will simply do nothing. The code doing what you are asking should be something like that:
Capture<Object> method1Param1 = newCapture();
tracerController.startTracer(capture(method1Param1)); // no need for the expect, it's the default
replay(tracerController);
// ...
tracerService.startTracer("TEST", "value1");
assertThat(method1Param1.getValue()).isEqualsTo("value1");
Of course, attendStartConditions and executeOnTracerControllerScope will be called for real.
Following your comment, if you want to mock executeOnTracerControllerScope, you will do the code below. However, your lambda won't be called anymore. So you won't be able to validate the param.
public class MyTest {
#Test
public void test() {
TracerController tracerController = mock(TracerController.class);
TracerService service = partialMockBuilder(TracerService.class)
.withConstructor(tracerController)
.addMockedMethod("executeOnTracerControllerScope")
.mock();
replay(tracerController);
service.startTracer("tracer", "param");
}
}
class TracerService {
private final TracerController tracerController;
public TracerService(TracerController tracerController) {
this.tracerController = tracerController;
}
public boolean attendStartConditions(String tracerName, Object param1) {
return true;
}
public void executeOnTracerControllerScope(Consumer<TracerController> tracer) {
tracer.accept(tracerController);
}
public void startTracer(String tracerName, Object param1) {
if (attendStartConditions(tracerName, param1)) {
executeOnTracerControllerScope(tracerController -> tracerController.startTracer(param1));
}
}
}
interface TracerController {
void startTracer(Object param1);
}

Mockito is calling real method and thenReturn does not work

I have read some post about it but nothing solved my problem. I have a class which is singleton and one method of this class is being called inside another class. I need to mock this method call.
Class SingletonClass
{
public static SingletonClass instance()
{
......
return instance;
}
public boolean methodToBeMocked(Object obj)
{
return false;
}
}
And the another class is :
Class A
{
Object doSomeStuff()
{
......
boolean result = SingletonClass.instance.methodToBeMocked();
}
}
And I am mocking the method methodToBeMocked in my test class. I have tried to use doReturn instead of thenReturn as it is suggested in other posts but it did not help.
My test class is :
Class TestClass{
Class A a = new A();
public void test()
{
SingletonClass singletonClass = mock(SingletonClass.class);
doReturn(true).when(singletonClass).methodToBeMocked(any());
a.doSomeStuff(); // here mocked method returns false
// but if I do this below it returns true !!!!
Object obj = new Object();
boolean result = singletonClass.mockedMethod(obj);
}
}
So why I am not getting true when a.doSomeStuff is called ? What is wrong here ?
For the benefit of others, I was using the following mock with the expectation it would not call someMock.someMethod(), unlike the when(someMock.someMethod()).doReturn("someString") usage.
Mockito.doReturn("someString").when(someMock).someMethod();
I could not understand why the real someMethod() was still being called. It turns out the method was specified as final. Mockito can't mock static or final methods.
The problem is the static method public static SingletonClass instance(). The standard mockito library does not support mocking of static methods. I seen two solutions.
You can rewrite small your code as:
Add new method getSingletonClassInstance() to be mocked in test
Class A {
Object doSomeStuff()
{
......
boolean result = getSingletonClassInstance();
}
SingletonClass getSingletonClassInstance(){
return SingletonClass.instance.methodToBeMocked();
}
}
use spy from mockito library to create an instance of Class A
import static org.mockito.Mockito.spy;
.....
Class TestClass{
public void test()
{
Class A a = spy(new A());
SingletonClass singletonClass = mock(SingletonClass.class);
doReturn(true).when(singletonClass).methodToBeMocked(any());
doReturn(singletonClass).when(a).getSingletonClassInstance();
a.doSomeStuff(); // here mocked method returns false
// but if I do this below it returns true !!!!
Object obj = new Object();
boolean result = singletonClass.mockedMethod(obj);
}
}
More information about the spy in mockito. Spy used real instance and invoke real method but provide a functionality to mock specific method. Don't worry about the others method they will continue to work with real implementation, only mocked method will be affected.
You can use power mockito to mock the public static SingletonClass
instance()

Mock Constructor with constructor-args Object... object

I want to mock a legacy object in my unit test. Here is constructor:
public Class LegacyClass{
public LegacyClass(Object... obj) {
super(obj);
}
}
I try to mock it using powerMock like this:
whenNew(LegacyClass.class).withParameterTypes(Object.class).
withArguments(anyString(), anyString()).thenAnswer(new Answer<Object>(){
...//Answer impl code
});
Here comes to questions:
Which Class I should put in withParameterTypes()?
Can I put this in #Before setup()?
Use Object[].class to access the parameter type of a varargs argument:
PowerMockito.whenNew(LegacyClass.class)
.withParameterTypes(Object[].class)
.withArguments(Mockito.anyString(), Mockito.anyString())
.thenAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock invocation)
throws Throwable {
// your code
}
});
I tested and this worked also in the #Before method.