Spring boot mock CREATED POST response - java

Completely new to spring-boot.
I am trying to write a test for my POST method that returns a response of CREATED with the path of the resource. I am coming across all sorts of problems for something that I was assuming is very straight forward. In the code bellow is my current test class which seems to be crashing with a
ClassNotFoundException
on the first line of my method.
#RunWith(SpringRunner.class)
#WebMvcTest(AResource.class)
public class AResourceTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private AResource aResourceMock;
#Test
public void testPOST() throws Exception {
Response.ResponseBuilder created = Response.created(UriBuilder.fromPath("/123").build());
when(aResourceMock.create(123)).thenReturn(created.build());
mockMvc.perform(MockMvcRequestBuilders
.request(HttpMethod.POST, "/account")
.content("{\t\"id\": \"123\"}"))
.andExpect(MockMvcResultMatchers.status().isCreated());
}
}
Any idea how to properly mock my response? Thanks
EDIT:
stacktrace bellow
java.lang.RuntimeException: java.lang.ClassNotFoundException: com.sun.ws.rs.ext.RuntimeDelegateImpl
at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:122)
at javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:91)
at javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:69)
at javax.ws.rs.core.UriBuilder.fromPath(UriBuilder.java:111)
at com.powerman.RestController.AResourceTest.canPOST(AResourceTest.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.ClassNotFoundException: com.sun.ws.rs.ext.RuntimeDelegateImpl
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at javax.ws.rs.ext.FactoryFinder.newInstance(FactoryFinder.java:62)
at javax.ws.rs.ext.FactoryFinder.find(FactoryFinder.java:155)
at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:105)
... 34 more
I will add my dependencies in case they help at all:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.0.1.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.17.1</version>
</dependency>
</dependencies>

I'm not sure what you are trying to do and why you would want to mock the Response. When you are running a a test for your resources, generally wha you want to do is run integration tests. What this entails is making an actual request to the endpoint using a client library. MockMvc only works when you are using Spring MVC as the REST framework. But in your case, you are using Jersey (I assume, based on the jax-rs tag in your post.
As far as the client library, you can use the Jersey/JAX-RS Client API or you can use Spring Boot's TestRestTemplate, like they do in the official Spring Boot/Jersey sample project. For checking the created URI for the POST/Created resource, what you should be doing is checking the Location header in the response. This is was is set on the server side when you do Response.created(URI). For example, say this is your resource
#Path("customers")
public class CustomersResource {
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response createCustomer(Customer customer, #Context UriInfo uriInfo) {
int customerId = // create customer and get the resource id
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(Integer.toString(customerId));
return Response.created(builder.build()).build();
}
}
Jersey will automatically set the Location to value of the URI passed to created()
Then (if you're using the Jersey Client), then your test might look something like
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ExampleResourceTest {
#LocalServerPort
private int port;
private Client client = ClientBuilder.newClient();
#Test
public void testCustomerLocationOnPost() {
Customer customer = new Customer("Jane", "Doe");
URI resourceUri = UriBuilder.fromUri("http://localhost")
.port(port).path("api").path("customers").build();
Response response = client.target(resourceUri).request().post(Entity.json(customer));
// test that we get the correct status code
assertThat(response.getStatus())
.isEqualTo(Response.Status.CREATED.getStatusCode());
// test that the location header is correct.
assertThat(response.getHeaderString(HttpHeaders.LOCATION))
.isEqualTo(UriBuilder.fromUri(resourceUri).path("123").build().toString());
}
}
As far as the dependencies, to use Jersey with Spring Boot you need to use the spring-boot-started-jersey dependency. Also get rid of the jersey-core dependency you have. See the linked project above for complete example.

Try adding to your pom.xml:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.27</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.27</version>
<scope>provided</scope>
</dependency>

Related

IBM MQ JMS application with Spring Boot. Getting exception:IBM MQ call failed '2538' ('MQRC_HOST_NOT_AVAILABLE')

I tried to create Spring boot IBM MQ application with Spring JMS.
Maven (pom.xml):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE </version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>mqspring</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>mqspring</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<webSphereMQVersion>7.5.0.1</webSphereMQVersion>
<springJMSVersion>4.0.0.RELEASE</springJMSVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>mq-jms-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.jms/jms -->
<dependency>
<groupId>javax.jms</groupId>
<artifactId>jms</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.ibm.mq</groupId>
<artifactId>com.ibm.mq.allclient</artifactId>
<version>9.0.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
Java:
#EnableJms
#SpringBootApplication
public class MqspringApplication {
#Autowired
private JmsTemplate jmsTemplate;
public static void main(String[] args) {
SpringApplication.run(MqspringApplication.class, args);
}
}
#PropertySource(ignoreResourceNotFound = true, value = "classpath:application.properties")
#Component
public class MessageSender
{
#Autowired
private JmsTemplate jmsTemplate;
#Value("${ibm.mq.queue}")
private String destination;
public void sendMessage() {
jmsTemplate.send(destination, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("ABC");
}
});
}
}
#Component
#PropertySource(ignoreResourceNotFound = true, value = "classpath:application.properties")
public class MessageReceiver {
#Autowired
private JmsTemplate jmsTemplate;
#JmsListener(destination = "ibm.mq.queue")
public String readMessage() throws JMSException {
System.out.println("Recieve");
String message = null;
Object msg = jmsTemplate.receiveAndConvert();
System.out.println("Message:::: "+msg.toString());
if(msg instanceof TextMessage) {
message = ((TextMessage) msg).getText();
System.out.println("Message" + message);
}
return message;
}
}
Config (application.properties):
ibm.mq.queueManager=MQS1
ibm.mq.queue=IDSMQ.REQUEST.FROM.RTPMQ
ibm.mq.hostname=localhost
ibm.mq.port=1415
Tests:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = MqspringApplication.class)
public class SimpleListenerTest {
#Autowired
private MessageSender msgService;
#Autowired
private MessageReceiver msgReceiver;
#Test
public void sendSimpleMessageSender() throws JMSException {
msgService.sendMessage();
}
#Test
public void sendSimpleMessageReceiver() throws JMSException {
msgReceiver.readMessage();
}
}
When I execute the test cases I am unable to connect to the IBM MQ. Getting exception:
org.springframework.jms.IllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'MQS1' with connection mode 'Client' and host name 'localhost(1414)'.; nested exception is com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'MQS1' with connection mode 'Client' and host name 'localhost(1414)'.
Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.; nested exception is com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:274)
at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:185)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:507)
at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:584)
at com.example.mqspring.MessageService.sendMessage(MessageService.java:42)
at com.example.mqspring.SimpleListenerTest.sendSimpleMessage(SimpleListenerTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: com.ibm.msg.client.jms.DetailedIllegalStateException: JMSWMQ0018: Failed to connect to queue manager 'MQS1' with connection mode 'Client' and host name 'localhost(1414)'.
Check the queue manager is started and if running in client mode, check there is a listener running. Please see the linked exception for more information.
at com.ibm.msg.client.wmq.common.internal.Reason.reasonToException(Reason.java:489)
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:215)
at com.ibm.msg.client.wmq.internal.WMQConnection.<init>(WMQConnection.java:424)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createV7ProviderConnection(WMQConnectionFactory.java:8475)
at com.ibm.msg.client.wmq.factories.WMQConnectionFactory.createProviderConnection(WMQConnectionFactory.java:7815)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl._createConnection(JmsConnectionFactoryImpl.java:303)
at com.ibm.msg.client.jms.admin.JmsConnectionFactoryImpl.createConnection(JmsConnectionFactoryImpl.java:236)
at com.ibm.mq.jms.MQConnectionFactory.createCommonConnection(MQConnectionFactory.java:6016)
at com.ibm.mq.jms.MQConnectionFactory.createConnection(MQConnectionFactory.java:6041)
at org.springframework.jms.support.JmsAccessor.createConnection(JmsAccessor.java:196)
at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:494)
... 34 more
Caused by: com.ibm.mq.MQException: JMSCMQ0001: IBM MQ call failed with compcode '2' ('MQCC_FAILED') reason '2538' ('MQRC_HOST_NOT_AVAILABLE').
at com.ibm.msg.client.wmq.common.internal.Reason.createException(Reason.java:203)
... 43 more
Caused by: com.ibm.mq.jmqi.JmqiException: CC=2;RC=2538;AMQ9204: Connection to host 'localhost(1414)' rejected. [1=com.ibm.mq.jmqi.JmqiException[CC=2;RC=2538;AMQ9213
Can someone please help me to understand why I am getting above error.
If I am giving port 1415, Why its trying to connect to localhost(1414)?
I have checked listener, LISTENER.TCP is running on port 1415. Why is not connecting to Queue Manager MQS1?
I have Websphere MQ 7.5.0 version installed but dependency
com.ibm.mq.allclient points to version 9.0.5.0. Does it create any problem?
hostname and port are not valid properties. Use ibm.mq.connName as the documentation and samples show.
You properties file should be in below format.
ibm.mq.queueManager=QM1
ibm.mq.channel=DEV.ADMIN.SVRCONN
ibm.mq.connName=localhost(1414)
ibm.mq.user=admin
ibm.mq.password=passw0rd
https://developer.ibm.com/components/ibm-mq/tutorials/mq-jms-application-development-with-spring-boot/

org.openqa.selenium.json.JsonOutput.write(Ljava/lang/Object;)Lorg/openqa/selenium/json/JsonOutput; due to java.io.IOException: Incomplete document

I'm creating a new test framework from scratch using Spring Boot 2 and Appium. To write the tests I'm using JUnit which is already included in Spring Boot's spring-boot-starter-test POM along with many others. I added Appium to my POM and it now looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.automationexperiment</groupId>
<artifactId>one</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/io.appium/java-client -->
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>6.1.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
As for my tests, I have a DriverSetup class that looks like this:
#RunWith(SpringRunner.class)
#SpringBootTest
public class DriverSetup {
protected AndroidDriver<AndroidElement> driver;
#Before
public void setUp() throws MalformedURLException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME, "Android");
capabilities.setCapability(MobileCapabilityType.PLATFORM_VERSION, "6.0.1");
capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "DeviceName");
capabilities.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.google.android.gm");
capabilities.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".ConversationListActivityGmail");
URL myUrl = new URL("http://127.0.0.1:4723/wd/hub");
this.driver = new AndroidDriver<AndroidElement>(myUrl, capabilities);
this.driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
}
}
Finally, I have another class that extends from DriverSetup to make sure driver initialization is done before every test. It looks like this:
#RunWith(SpringRunner.class)
#SpringBootTest
public class FirstTryTest extends DriverSetup {
public FirstTryTest() { }
#Test
public void test() {
System.out.println("test");
}
}
I just want to make sure I can reach the test in my FirstTryTest, but every time the code initializes the AndroidDriver with the URL and the DesiredCapabilities, I get the following error:
java.lang.NoSuchMethodError: org.openqa.selenium.json.JsonOutput.write(Ljava/lang/Object;)Lorg/openqa/selenium/json/JsonOutput;
at io.appium.java_client.remote.NewAppiumSessionPayload.writeTo(NewAppiumSessionPayload.java:265)
at io.appium.java_client.remote.AppiumCommandExecutor$1.createSession(AppiumCommandExecutor.java:175)
at io.appium.java_client.remote.AppiumCommandExecutor.createSession(AppiumCommandExecutor.java:209)
at io.appium.java_client.remote.AppiumCommandExecutor.execute(AppiumCommandExecutor.java:231)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:601)
at io.appium.java_client.DefaultGenericMobileDriver.execute(DefaultGenericMobileDriver.java:42)
at io.appium.java_client.AppiumDriver.execute(AppiumDriver.java:1)
at io.appium.java_client.android.AndroidDriver.execute(AndroidDriver.java:1)
at org.openqa.selenium.remote.RemoteWebDriver.startSession(RemoteWebDriver.java:219)
at org.openqa.selenium.remote.RemoteWebDriver.<init>(RemoteWebDriver.java:142)
at io.appium.java_client.DefaultGenericMobileDriver.<init>(DefaultGenericMobileDriver.java:38)
at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:84)
at io.appium.java_client.AppiumDriver.<init>(AppiumDriver.java:94)
at io.appium.java_client.android.AndroidDriver.<init>(AndroidDriver.java:93)
at com.automationexperiment.one.driversetup.DriverSetup.setUp(DriverSetup.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at com.microsoft.java.test.runner.JUnit4TestReference.run(JUnit4TestReference.java:51)
at com.microsoft.java.test.runner.CustomizedJUnitCoreRunner.run(CustomizedJUnitCoreRunner.java:45)
at com.microsoft.java.test.runner.JUnitLauncher.execute(JUnitLauncher.java:26)
at com.microsoft.java.test.runner.JUnitLauncher.main(JUnitLauncher.java:15)
Suppressed: java.io.IOException: Incomplete document
at com.google.gson.stream.JsonWriter.close(JsonWriter.java:559)
at org.openqa.selenium.json.JsonOutput.close(JsonOutput.java:39)
at io.appium.java_client.remote.NewAppiumSessionPayload.writeTo(NewAppiumSessionPayload.java:288)
... 41 more
I've tried using an older version of Appium (5.0.4) but it didn't work. I'd like to emphasize the end of the StackTrace. An IOException is mentioned while in other questions with similar errors script fails due to a
org.openqa.selenium.json.JsonException`.
This error message:
java.lang.NoSuchMethodError: org.openqa.selenium.json.JsonOutput.write(Ljava/lang/Object;)Lorg/openqa/selenium/json/JsonOutput;
.
Suppressed: java.io.IOException: Incomplete document
...implies that java.lang.NoSuchMethodError was raised by the JVM.
You have mentioned about using an older version of Appium v5.0.4
It's pretty tough to analyze the error in absence of the following information pertaining to your Test Environment:
Appium server version
Desktop OS/version
Mobile platform/version under test
Real device or emulator/simulator
As per the discussions Error while running Appium script with AndroidDriver and iOS :Could not initialize the ios capabilities with 6.0.0 this error seems to be coming from the NumberCoercer Class which have been modified in Selenium RemoteDriver v3.12.0 to accept Port as Integer while earlier it was accepting String.
Solution
Update to the latest Appium Java Client v6.1.0
Update to the latest (atleast) Selenium v3.12.0
#SrinivasanTarget mentions one important aspect that:
Appium's Java client comes along with Selenium Dependency so we don't recommend to exclude selenium and add as separate dependency as it may raise conflicts at times.
Here you will find a relevant discussion on java.lang.NoSuchMethodError: org.openqa.selenium.json.JsonOutput.write(Ljava/lang/Object;Ljava/lang/reflect/Type;)

ExceptionMapper not working in JerseyTest framework

I had made an RESTFUL-API for an specific object and using javax.validation.Constraints for validation, when I execute the app it works as expected and ExceptionMapper class is been executed correctly but when I try to automatize tests with JerseyFramework the ExceptionMapper is not executed or handled. So it works in app but not when i test it.
Main Class that launch app
package com.carlos.zerga.server;
public class App {
public static void main( String[] args ) throws Exception {
AppResourceConfig config = new AppResourceConfig();
ServletHolder jerseyServlet
= new ServletHolder(new ServletContainer(config));
Server server = new Server(8081);
ServletContextHandler context
= new ServletContextHandler(server, "/");
context.addServlet(jerseyServlet, "/*");
server.start();
server.join();
}
}
ResourceConfig for App
package com.carlos.zerga.server;
public class AppResourceConfig extends ResourceConfig{
public AppResourceConfig() {
register(new PropertiesBinder());
register(EntityValidationExceptionMapper.class);
packages(true,"com.carlos.zerga.properties");
}
}
ExceptionMapper for ValidationExceptions
package com.carlos.zerga.properties.presentation.handler;
#Provider
public class EntityValidationExceptionMapper implements
ExceptionMapper<BeanValidationException> {
public Response toResponse(BeanValidationException e) {
return Response.status(200).
type(MediaType.APPLICATION_JSON_TYPE).
entity(buildResponse((ConstraintViolationException) e.getInternalException())).
build();
}
private ExceptionResponse buildResponse(ConstraintViolationException e)
{
ArrayList<String> messages = new ArrayList<String>();
for(ConstraintViolation constraintViolation:e.getConstraintViolations())
{
messages.add(constraintViolation.getMessage());
}
return new ExceptionResponse(200, messages,e.getClass().getSimpleName());
}
}
Resouce Class
package com.carlos.zerga.properties.presentation;
#Path("property")
public class PropertiesApiResource {
#POST
#Path("new")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Property createProperty(Property property)
{
return property;
}
//LOT OF OTHER ROUTES
......
}
Test Case
package com.carlos.zerga.test.properties.presentation;
#RunWith(DataProviderRunner.class)
public class PropertiesApiResourceTest extends JerseyTest {
#Override
protected Application configure() {
return new ResourceConfig()
.register(new PropertiesBinder())
.register(new EntityValidationExceptionMapper())
.register(new ConstraintValidationException())
.packages(true,"com.carlos.zerga.properties");
}
//Here comes the error
#Test
#UseDataProvider("provideInvalidPropertiesPSR_PA")
public void testInValidPropertyCreation(Property property)
{
Response response=target("property/new").request(MediaType.APPLICATION_JSON).method("POST",Entity.json(property));
assertEquals(response.getMediaType(),MediaType.APPLICATION_JSON_TYPE);
String exceptionResponse=response.readEntity(String.class);
System.out.print(exceptionResponse);
}
POM.xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet-core</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>hk2-metadata-generator</artifactId>
<version>2.4.0</version>
</dependency>
<dependency>
<groupId>com.tngtech.java</groupId>
<artifactId>junit-dataprovider</artifactId>
<version>1.12.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework</groupId>
<artifactId>jersey-test-framework-core</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.test-framework.providers</groupId>
<artifactId>jersey-test-framework-provider-jetty</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.ext</groupId>
<artifactId>jersey-bean-validation</artifactId>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.connectors</groupId>
<artifactId>jersey-jetty-connector</artifactId>
<version>${jersey.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<jersey.version>2.26-b03</jersey.version>
<jetty.version>9.2.14.v20151106</jetty.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
When I send by postman it returns me what I want:
{"errorCode":200,"errors":["Bathroom : Amount bathrooms can't be empty"],"errorDescription":"ConstraintViolationException"}
But when I run the tests returns me:
javax.ws.rs.ProcessingException:
Exception Description: Constraints violated on marshalled bean:
com.carlos.zerga.properties.domain.entity.Property#3caeaf62
-->Violated constraint on property bathRooms: "Bathroom : Minimun amout of bathrooms is 3".
-->Violated constraint on property bedRooms: "Bathroom : Minimun amout of bathrooms is 3".
Internal Exception: javax.validation.ConstraintViolationException
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:262)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:759)
at org.glassfish.jersey.client.JerseyInvocation$1.call(JerseyInvocation.java:756)
at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
at org.glassfish.jersey.internal.Errors.process(Errors.java:228)
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:407)
at org.glassfish.jersey.client.JerseyInvocation.invoke(JerseyInvocation.java:756)
at org.glassfish.jersey.client.JerseyInvocation$Builder.method(JerseyInvocation.java:443)
at com.carlos.zerga.test.properties.presentation.PropertiesApiResourceTest.testInValidPropertyCreation(PropertiesApiResourceTest.java:93)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at com.tngtech.java.junit.dataprovider.DataProviderFrameworkMethod.invokeExplosively(DataProviderFrameworkMethod.java:77)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: Exception [EclipseLink-7510] (Eclipse Persistence Services - 2.6.4.v20160829-44060b6): org.eclipse.persistence.exceptions.BeanValidationException
Exception Description: Constraints violated on marshalled bean:
com.carlos.zerga.properties.domain.entity.Property#3caeaf62
-->Violated constraint on property bathRooms: "Bathroom : Minimun amout of bathrooms is 3".
-->Violated constraint on property bedRooms: "Bathroom : Minimun amout of bathrooms is 3".
Internal Exception: javax.validation.ConstraintViolationException
at org.eclipse.persistence.exceptions.BeanValidationException.constraintViolation(BeanValidationException.java:53)
at org.eclipse.persistence.jaxb.JAXBBeanValidator.buildConstraintViolationException(JAXBBeanValidator.java:391)
at org.eclipse.persistence.jaxb.JAXBBeanValidator.validate(JAXBBeanValidator.java:275)
at org.eclipse.persistence.jaxb.JAXBMarshaller.validateAndTransformIfNeeded(JAXBMarshaller.java:604)
at org.eclipse.persistence.jaxb.JAXBMarshaller.marshal(JAXBMarshaller.java:494)
at org.eclipse.persistence.jaxb.rs.MOXyJsonProvider.writeTo(MOXyJsonProvider.java:957)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:265)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.aroundWriteTo(WriterInterceptorExecutor.java:250)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor.proceed(WriterInterceptorExecutor.java:162)
at org.glassfish.jersey.message.internal.MessageBodyFactory.writeTo(MessageBodyFactory.java:1126)
at org.glassfish.jersey.client.ClientRequest.doWriteEntity(ClientRequest.java:517)
at org.glassfish.jersey.client.ClientRequest.writeEntity(ClientRequest.java:499)
at org.glassfish.jersey.client.internal.HttpUrlConnector._apply(HttpUrlConnector.java:393)
at org.glassfish.jersey.client.internal.HttpUrlConnector.apply(HttpUrlConnector.java:285)
at org.glassfish.jersey.client.ClientRuntime.invoke(ClientRuntime.java:253)
... 34 more
Caused by: javax.validation.ConstraintViolationException
at org.eclipse.persistence.jaxb.JAXBBeanValidator.buildConstraintViolationException(JAXBBeanValidator.java:389)
... 47 more
If you look carefully at the stacktrace, you will see that this error is actually happening on the client side, even before the request gets to the server. The reason is that you are using MOXy, which uses JAXB, and the JAXB bean validation is enabled by default. You can see in the stacktrace that the JAXBBeanValidator is being envoked, and that it is happening on the client side marshalling of the entity.
There are a couple solutions:
Configure MOXy to disable bean validation
Don't use MOXy
Configure MOXy to disable bean validation
To configure MOXy, you can use a MoxyJsonConfig. You should actually do this on the server side also so that you don't get double validation on the server. The bean validation provided by Jersey is different from that provided by MOXy.
In Test.java
#Override
public void configureClient(ClientConfig config) {
config.register(new MoxyJsonConfig().setFormattedOutput(true)
.property(MarshallerProperties.BEAN_VALIDATION_MODE, BeanValidationMode.NONE)
.resolver());
}
The configureClient method is a method on the JerseyTest that you can override to configure the Client. You can register the same MoxyJsonConfig with the ResourceConfig also for the server side.
Don't use MOXy
My solution would be to just get rid of MOXy, and use Jackson instead. Just change the following dependency to the Jackson on below it
<!-- remove this -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-moxy</artifactId>
<version>${jersey.version}</version>
</dependency>
<!-- use this -->
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>${jersey.version}</version>
</dependency>
And also add #Valid tag to:
Resource.java
...... MORE ROUTES
#POST
#Path("new")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Property createProperty(#Valid Property property){
return property;
}
...... MORE ROUTES
You will not have this problem with Jackson as Jackson doesn't do any bean validation. Aside from this problem, my personal opinion is that Jackson is just a much better overall library for JSON anyway.
Note: If you turn off the MOXy validation (whether through configuration or by using Jackson), you would no longer be trying to catch a BeanValidationException (which is a MOXy) class, but instead you can directly catch ConstraintViolationException.

No such method error while using RestAssuredMockMvc

I'm using RestAssuredMockMvc for unit testing spring mvc controllers.
This is my code:
import com.xyz.api.controller.UserController;
import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc;
import org.junit.Before;
import org.junit.Test;
import javax.servlet.http.HttpServletResponse;
import static org.hamcrest.Matchers.equalTo;
public class UserControllerRest {
private String userName = "xyz#example.com";
private String expectedResult = "Hello " + userName;
#Before
public void initialize() {
RestAssuredMockMvc.standaloneSetup(new UserController());
}
#Test
public void checkResponseAndBody() throws Exception {
RestAssuredMockMvc.given().param("userName", userName).when().get("/users").print();
RestAssuredMockMvc.given().param("userName", userName).when().get("/users").then().assertThat().statusCode(200).and().body(equalTo(expectedResult));
}
}
The first statement in checkResponseAndBody() prints: Hello xyz#example.com
But the second line gives the following error:
java.lang.NoSuchMethodError: com.jayway.restassured.internal.ValidatableResponseOptionsImpl.<init>(Ljava/lang/String;Lcom/jayway/restassured/internal/ResponseParserRegistrar;Lcom/jayway/restassured/config/RestAssuredConfig;Lcom/jayway/restassured/response/Response;Lcom/jayway/restassured/response/ExtractableResponse;)V
at com.jayway.restassured.module.mockmvc.internal.ValidatableMockMvcResponseImpl.<init>(ValidatableMockMvcResponseImpl.java:37)
at com.jayway.restassured.module.mockmvc.internal.MockMvcRestAssuredResponseImpl.then(MockMvcRestAssuredResponseImpl.java:36)
at com.giddh.api.restassured.UserControllerRest.checkResponseAndBody(UserControllerRest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
I've seen the examples and even tried using the same code but still the error persists. How can I solve this?
You've probably not added all dependencies to your classpath. As indicated by the download page you also need to download and put the contents of rest-assured-2.5.0-dist.zip in your classpath.
If you're using Maven it should be enough to just depend on the spring-mock-mvc module:
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>spring-mock-mvc</artifactId>
<version>${rest-assured.version}</version>
<scope>test</scope>
</dependency>
Or gradle:
testCompile "com.jayway.restassured:spring-mock-mvc:${rest-assured.version}"
This happened to me when using restassured with Maven (Surprisingly, Gradle did not give me this problem, it handled it well unlike Maven).
For me, it was a dependency conflict. I had Apache Phoenix as dependency in my pom.xml
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix</artifactId>
<version>4.13.2-cdh5.11.2</version>
This Apache Phoenix jar depends on httpclient version 4.0.1 jar which overrides the version which my restassured jar depends on (which is httpclient version 4.3.5) . Maven had excluded this later version (4.5.3) by default.
To solve this, I added exclusion for the older version under my Apache Phoenix pom section which looked like this:
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>4.13.2-cdh5.11.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
That way the version of httpclient in my restassured jar superceded and everything worked fine.

PowerMock PrepareForTest annotation causing problems with AmazonSQSClient constructor

I'm having some trouble with the PrepareForTest annotation and creating a new instance of an AmazonSQSClient.
I'm writing a Jenkins plugin and unfortunately need to mock the FormValidation static class in order to ensure that warning and error messages are produced on field validation of my plugin. However when creating an instance of AmazonSQSClient I get an org.apache.http.conn.ssl.SSLInitializationException
I've abstracted it down to a very simple example, here's my test file:
package com.test;
import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSClient;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
public class SQSTest {
// This is for mimicking the mocking of FormValidation
private static class Foo {}
#Test
#PrepareForTest(Foo.class)
public void buildTest()
{
AmazonSQS sqs = new AmazonSQSClient();
}
}
On running this code I get the following error:
org.apache.http.conn.ssl.SSLInitializationException: Failure initializing default SSL context
at org.apache.http.conn.ssl.SSLSocketFactory.createDefaultSSLContext(SSLSocketFactory.java:360)
at org.apache.http.conn.ssl.SSLSocketFactory.getSocketFactory(SSLSocketFactory.java:175)
at org.apache.http.impl.conn.SchemeRegistryFactory.createDefault(SchemeRegistryFactory.java:49)
at org.apache.http.impl.conn.PoolingClientConnectionManager.<init>(PoolingClientConnectionManager.java:93)
at com.amazonaws.http.ConnectionManagerFactory.createPoolingClientConnManager(ConnectionManagerFactory.java:26)
at com.amazonaws.http.HttpClientFactory.createHttpClient(HttpClientFactory.java:87)
at com.amazonaws.http.AmazonHttpClient.<init>(AmazonHttpClient.java:121)
at com.amazonaws.AmazonWebServiceClient.<init>(AmazonWebServiceClient.java:66)
at com.amazonaws.services.sqs.AmazonSQSClient.<init>(AmazonSQSClient.java:189)
at com.amazonaws.services.sqs.AmazonSQSClient.<init>(AmazonSQSClient.java:93)
at com.test.SQSTest.buildTest(SQSTest.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:88)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:96)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:118)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:101)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:53)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.security.NoSuchAlgorithmException: class configured for KeyManagerFactory: sun.security.ssl.KeyManagerFactoryImpl$SunX509 not a KeyManagerFactory
at sun.security.jca.GetInstance.checkSuperClass(GetInstance.java:258)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:237)
at sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
at javax.net.ssl.KeyManagerFactory.getInstance(KeyManagerFactory.java:138)
at org.apache.http.conn.ssl.SSLSocketFactory.createSSLContext(SSLSocketFactory.java:223)
at org.apache.http.conn.ssl.SSLSocketFactory.createDefaultSSLContext(SSLSocketFactory.java:358)
... 42 more
In order to help anyone wanting to build and run this quickly here is my pom.xml file:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>test.sqs</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>hpi</packaging>
<properties>
<!--
explicitly specifying the latest version here because one we get from the parent POM
tends to lag behind a bit
-->
<maven-hpi-plugin.version>1.96</maven-hpi-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.5.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.5.1</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.5.1</version>
</dependency>
</dependencies>
</project>
When the annotation #PrepareForTest(Foo.class) is removed from the method the test runs fine.
I was wondering if someone could explain why this is happening and if there is a work around for it or a way to avoid mocking the FormValidation class?
Thanks.
Try to add #PowerMockIgnore("org.apache.http.conn.ssl.*") annotation to your class
As #Natalie already mentioned, you can work with the #PowerMockIgnore() annotation. Maybe you need to ignore the packages javax.net.ssl.* and / or javax.crypto.*:
#PowerMockIgnore({"org.apache.http.conn.ssl.*", "javax.net.ssl.*" , "javax.crypto.*"})
You can get here some background information:
https://groups.google.com/forum/#!topic/powermock/v4nreP2AnOQ
This is most likely because SSLContext is loaded by the bootstrap classloader and PowerMock cannot byte-code manipulate these classes. You have to use this approach to mock that method.
/Johan Haleby

Categories

Resources