How to pass superclass object to restful service (jersey) - web-services

I have two POJOs
#XmlRootElement
public class PojoBase {
}
#XmlRootElement
public class PojoRequest extends PojoBase {
private String strTemplate;
public void setTemplate(String strTemplate) {
this.strTemplate = strTemplate;
}
public String getTemplate() {
return strTemplate;
}
}
#XmlRootElement
public class PojoResponse extends PojoBase {
private String strName;
public void setName(String strName) {
this.strName = strName;
}
public String getName() {
return strName;
}
}
I have service which accepts the base class and returns the base class as response.
#POST
#Path("/start")
#Produces({MediaType.APPLICATION_JSON})
#Consumes(MediaType.APPLICATION_JSON)
public PojoBase registerNumber(JAXBElement<PojoBase> theRequest) {
//does some work with theRequest.
//here the theRequest object doesn't has pojoRequest data.
PojoResponse pojoResponse = new PojoResponse();
pojoResponse.setName("Sample");
return pojoResponse;
}
From client I am sending pojo base object but not sure why Restful doesn't get actual theRequest object.
Here is the client code:
public class HttpClient {
static String _strServiceURL = "http://127.0.0.1:8080/middleware/rest/service/start";
public static void main(String[] args) throws Exception {
PojoRequest pojoRequest = new PojoRequest();
pojoRequest.setTemplate("Somedata");
PojoBase response = getResponse(pojoRequest);
PojoResponse pojoresponse = (PojoResponse) response;
System.out.println(response);
}
private static PojoBase getResponse(PojoBase request) {
try {
Client client = Client.create();
WebResource webResource = client.resource(_strServiceURL);
ClientResponse response = webResource.type(javax.ws.rs.core.MediaType.APPLICATION_JSON).post(ClientResponse.class, request);
System.out.println(response.getStatus());
if(response.getStatus() == 200){
PojoBase response = response.getEntity(PojoBase.class);
return response;
}
} catch(Exception e) {
System.out.println(e.getMessage());
}
return null;
}
}
Can you please tell me how to get the PojoRequest at Service end?
Any help is appreciated.
Thanks

I don't think you can pass a superclass to jersey like this. I believe, though I may be wrong, that as registerNumber() has a parameter JAXBElement<PojoBase> it will do something like:
instantiate a PojoBase
do reflection on PojoBase (which has no properties), therefore nothing to set.
call registerNumber() with the practically empty PojoBase object
So why not try changing the signature to:
public PojoBase registerNumber(JAXBElement< PojoRequest > theRequest)
or even (with com.sun.jersey.api.json.POJOMappingFeature = true):
public PojoBase registerNumber(PojoRequest theRequest)

Related

PowerMock calls real method

I am trying to spy private method with PowerMock but on the line when I define the what should be returned when the private method is called, it calls the method and I am getting and Null Pointer Exception. What PowerMock is calling real method on this line ?
myService= PowerMockito.spy(new MyService(myParam));
.....
PowerMockito.when(myService, "getCLientBy", anyString(), anyString(), anyString()).thenRetur`n(Client.of(setName, new HashSet<>())); // here it calls real method
Ensure that you prepare your class to be used in spy by adding #PrepareForTest(MyService.class)
#RunWith(PowerMockRunner.class)
// We prepare MyService for test because it's final
// or we need to mock private or static methods
#PrepareForTest(MyService.class)
public class YourTestCase {
//...
#Test
public void spyingWithPowerMock() {
MyService classUnderTest = PowerMockito.spy(new MyService(myParam));
//.....
// use PowerMockito to set up your expectation
PowerMockito.doReturn(Client.of(setName, new HashSet<>()))
.when(classUnderTest, "getClientBy", anyString(), anyString(), anyString());
//...
Also make sure provide the correct method name to be invoked.
#user1474111 and #Nkosi
I've built a small simulation of your example.
Maybe you also need to add the Client class in the PrepareForTest annotation.
#RunWith(PowerMockRunner.class)
#PrepareForTest({ MyService.class, Client.class })
public class Example1Test {
#Test
public void testPowerMockito() throws Exception {
MyService myService = PowerMockito.spy(new MyService("myParam"));
PowerMockito.when(myService, "getClientBy", ArgumentMatchers.anyString(), ArgumentMatchers.anyString(),
ArgumentMatchers.anyString()).thenReturn(Client.of("setName", new HashSet<String>()));
myService.run();
Assert.assertEquals("setName", myService.getClient().getName());
}
}
public class MyService {
private Client client;
public MyService(String param) { }
private Client getClientBy(String a, String b, String c) {
return new Client(a + b + c);
}
public Client getClient() {
return this.client;
}
public void setClient(Client client) {
this.client = client;
}
public void run() {
setClient(getClientBy("A", "B", "C"));
}
}
public class Client {
private final String name;
public Client(String name) {
this.name = name;
}
public static Client of(String name, HashSet<String> hashSet) {
return new Client(name);
}
public String getName() {
return name;
}
}

PowerMockito Mocked final class gson.fromJson() Returns null

I have this code in main class -
try {
extraPlayer = gson.fromJson(jsonResponse, ExtraPlayer.class);// this returns null
} catch (Exception e) {
e.printStacktrace();
}
Here extraPlayer is coming as null
I have mocked #Mock Gson gsonMock;
Here ExtraPlayer is a static class.
I have written this test code -
#Test
public void test() {
String jsonResponse = "{\"status\":\"waiting\",\"no\":\"12\"}";
when(playerHandlerMock.resetPlayer("someString", "someString", "1",true
)).thenReturn(jsonResponse);
Gson gsonMock = PowerMockito.mock(Gson.class);
ExtraPlayer extraPlayer = new ExtraPlayer();
extraPlayer.setNo("12");
extraPlayer.setStatus("Waiting");
PowerMockito.mockStatic(ResetModemResponse.class); // using this for static class but didn't work.
PowerMockito.when(gsonMock.fromJson(jsonResponse, ExtraPlayer.class)).thenReturn(extraPlayer);
playerMock.performWaiting();
}
ExtraPlayer.java
public static class ExtraPlayer{
String no;
String status;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getNo() {
return code;
}
public void setNo(String no) {
this.no = no;
}
}
I have added these annotations to the test class -
#RunWith(PowerMockRunner.class)
#PrepareForTest(Gson.class)
why extraPlayer is null ? please help/Suggest.
If you were to use the standard #Mock and #InjectMocks annotation with mockito, then yes, the framework would take care of the injection of the mock into the class under test (regardless of the existence of the setters etc.).
Another thing is the playerMock, which i assume is the class under test.
Do not mock the class under test, create a normal instance and then inject the dependencies... the performWaiting method does not seem to accept the response String, so you would have to inject that also somehow (unless you left some parts out):
#Test
public void test() {
// Arrange
String jsonResponse = "{\"status\":\"waiting\",\"no\":\"12\"}";
Gson gsonMock = PowerMockito.mock(Gson.class);
ExtraPlayer extraPlayer = new ExtraPlayer();
extraPlayer.setNo("12");
extraPlayer.setStatus("Waiting");
PowerMockito.when(gsonMock.fromJson(jsonResponse, ExtraPlayer.class)).thenReturn(extraPlayer);
Player player = new Player();
player.setGson(gsonMock);
player.setResponse(jsonResponse);
// Act
player.performWaiting();
// Assert ...
}

How to mock private method using JMockit by using withInstanceOf?

I needed to know that how to mock private method by using withInstanceOf in JMockit?
Here is the class I need to test.
package mockingPrivateMethodWithInstanceOf;
public class Simple
{
private String iAmPrivate(String argString)
{
return "Private Method";
}
public String publicCallsPrivate()
{
String string = "aString";
return iAmPrivate(string);
}
}
Here is the test class
public class SimpleTest
{
#Test
public void testPublicInvokesPrivate()
{
final Simple simple = new Simple();
new Expectations(simple)
{
{
Deencapsulation.invoke(simple, "iAmPrivate", withInstanceOf(String.class));
returns("Mocked method");
}
};
assertEquals("Mocked method", simple.publicCallsPrivate());
}
}
When test class is executed it says:
java.lang.IllegalArgumentException: Invalid null value passed as argument 0

Rest Web Service using Interfaces

I am trying to create a REST web-service in Java using RestEasy with the design similar to the example classes that I have shown below:
#Path("/rest")
public class TestRestService {
#GET
#Path("/test")
#Produces("application/xml")
public Response sayTestXml() {
return getImplementation();
}
public Response getImplementation() {
IInterface refToImpl = TestService.getImplementation();
return Response.status(Status.OK).entity(refToImpl).build();
}
}
public class TestService {
public static IInterface getImplementation() {
IInterface ref = new Implementation();
return ref;
}
}
public interface IInterface {
public long getLong();
public String getString();
public boolean getBoolean();
public List<IRelatedInterface> getRelations();
}
public interface IRelatedInterface {
public float getFloat();
public char getChar();
public byte getByte();
}
#XmlRootElement(name="interface")
#XmlAccessorType(XmlAccessType.PROPERTY)
public class Implementation implements IInterface {
#XmlElement(name="tlong", required=true)
public long getLong() {
return 42;
}
#XmlElement(name="tstring", required=true)
public String getString() {
return "test";
}
#XmlElement(name="tboolean", required=true)
public boolean getBoolean() {
return false;
}
#XmlElementWrapper(name = "relations")
#XmlElement(name = "relation", required=false)
public List<IRelatedInterface> getRelations() {
List<IRelatedInterface> list = new ArrayList<IRelatedInterface>();
RelatedImplementation impl = new RelatedImplementation();
list.add(impl);
return list;
}
}
#XmlRootElement(name="relatedInterface")
#XmlAccessorType(XmlAccessType.PROPERTY)
public class RelatedImplementation implements IRelatedInterface {
#XmlElement(name="tfloat", required=true)
public float getFloat() {
return 1.23f;
}
#XmlElement(name="tchar", required=true)
public char getChar() {
return 'A';
}
#XmlElement(name="tbyte", required=true)
public byte getByte() {
return 'Z';
}
}
So, when I try this design then JAXB complains as below:
com.sun.xml.bind.v2.runtime.IllegalAnnotationsException:
2 counts of IllegalAnnotationExceptions com.intuit.whitespace.IRelatedInterface is an interface, and JAXB can't handle interfaces.
this problem is related to the following location: at com.intuit.whitespace.IRelatedInterface at public java.util.List com.intuit.whitespace.Implementation.getRelations() at com.intuit.whitespace.Implementation com.intuit.whitespace.IRelatedInterface does not have a no-arg default constructor. this problem is related to the following location: at com.intuit.whitespace.IRelatedInterface at public java.util.List com.intuit.whitespace.Implementation.getRelations() at com.intuit.whitespace.Implementation
My question is, is there a way to solve this? I have tried some things but none of them have worked. I am considering Spring OXM or a MessageBodyWriter based solution, but I wanted to ask if there were any other suggestions that would help me better?
Okay, I solved it by making the following changes:
Used the type attribute in #XmlElement
public class Implementation implements IInterface {
#XmlElementWrapper(name = "relations")
#XmlElement(name = "relation", required=false, type=RelatedImplementation.class)
public List<IRelatedInterface> getRelations() {
....
}
}
That is all!

Mocking digest authentication in RestEasy

I am using RestEasy to develop a REST server and using the mock dispatcher (org.jboss.resteasy.mockMockDispatcherFactory) for testing the service in my unit tests. My service requires digest authentication and I would to make that part of my testing.
Each of my services accepts a #Context SecurityContext securityContext parameter.
Is there any way is inject a fake SecurityContext in the dispatcher so that I can test that my security methods function properly?
You have to add the SecurityContext into the context data map in ResteasyProviderFactory.
public class SecurityContextTest {
#Path("/")
public static class Service {
#Context
SecurityContext context;
#GET
public String get(){
return context.getAuthenticationScheme();
}
}
public static class FakeSecurityContext extends ServletSecurityContext {
public FakeSecurityContext() {
super(null);
}
#Override
public String getAuthenticationScheme() {
return "unit-test-scheme";
}
}
#Test
public void securityContextTest() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getRegistry().addSingletonResource(new Service());
ResteasyProviderFactory.getContextDataMap().put(SecurityContext.class, new FakeSecurityContext());
MockHttpRequest request = MockHttpRequest.get("/");
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals("unit-test-scheme", response.getContentAsString());
}
}
For those coming across this issue today, adding Contexts has been moved from the RestEasyProviderFactory class into the Dispatcher class using getDefaultContextObjects() method.
I've edited the old answer with the new call:
public class SecurityContextTest {
#Path("/")
public static class Service {
#Context
SecurityContext context;
#GET
public String get(){
return context.getAuthenticationScheme();
}
}
public static class FakeSecurityContext extends ServletSecurityContext {
public FakeSecurityContext() {
super(null);
}
#Override
public String getAuthenticationScheme() {
return "unit-test-scheme";
}
}
#Test
public void securityContextTest() throws Exception {
Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
dispatcher.getRegistry().addSingletonResource(new Service());
dispatcher.getDefaultContextObjects().put(SecurityContext.class, new FakeSecurityContext());
MockHttpRequest request = MockHttpRequest.get("/");
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals("unit-test-scheme", response.getContentAsString());
}
}