Spring Boot - Rest Assured methods not found - java

I have a REST API built with Spring Boot.
I am attempting to use Rest-Assured test framework, however I can't seem to get it to work.
I am using the guide from Here
get("/lotto").then().assertThat().body("lotto.lottoId", equalTo(5));
And have added the dependencies to my maven project.
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>rest-assured</artifactId>
<version>2.9.0</version>
<scope>test</scope>
</dependency>
However, It doesn't seem to import the required classes and just prompts me to create a new "get()" method.
My Test class:
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(Application.class)
#WebIntegrationTest
public class DemoControllerTest {
#Test
public void test() {
get("/lotto").then().assertThat().body("lotto.lottoId", equalTo(5));
}
}
What am I missing?

What am I missing?
A simple static import, that's missing! In order to resolve the get static method, just use the following static import:
import static com.jayway.restassured.RestAssured.get;

I had similar issue. What I did (using new version 3.0.2):
import io.restassured.RestAssured.*;
import io.restassured.matcher.RestAssuredMatchers.*;
import org.hamcrest.Matchers.*;
Instead of:
import static io.restassured.RestAssured.*;
import static io.restassured.matcher.RestAssuredMatchers.*;
import static org.hamcrest.Matchers.*;
So I had same issue couldnt find the methods ...

Related

Unable to run any Junit4 tests - InvalidTestClassError: Invalid test class

I am trying to run Junit4 tests and I am unable to run it. I have the following dependency installed
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
My test class looks like this
package model.validators;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
class UserValidatorTest {
#Test
public void shouldReturnTrueForValidPhoneNumbers() {
List<String> phoneNumbers = Arrays.asList(
"9876543210",
"7777543210"
);
boolean result = UserValidator.validateUserPhoneNumbers(phoneNumbers);
Assert.assertTrue(result);
}
}
When I try to run this test, I get the following error
org.junit.runners.model.InvalidTestClassError: Invalid test class 'model.validators.UserValidatorTest':
I am using IntellijIdea. Any idea what is going wrong here ? TIA
Tried changing dependencies, reloading maven project, setting the correct classpath in Junit Run configurations
I can see that your class UserValidatorTest is not public. On making your class public, you will be able to run the tests.
package model.validators;
import org.junit.Assert;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class UserValidatorTest {
#Test
public void shouldReturnTrueForValidPhoneNumbers() {
List<String> phoneNumbers = Arrays.asList(
"9876543210",
"7777543210"
);
boolean result = UserValidator.validateUserPhoneNumbers(phoneNumbers);
Assert.assertTrue(result);
}
}
JUnit4 requires everything to be public.
JUnit5 is more tolerant regarding the visibilities of Test classes (Test classes, test methods, and lifecycle methods are not required to be public, but they must not be private).
SonarLint Rule description:
In this context (JUnit5), it is recommended to use the default package visibility, which improves the readability of code.

How to mock S3 in order to test Java code in Junit

I have taken reference form here in order to implement S3 mocking for integration testing
My confusion and the part that i did not get is that how can i use docker here ?
Do i have to install something ?
I have just added below code in my maven
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-datapipeline</artifactId>
<version>1.11.295</version>
</dependency>
And have written below class
package com.amazonaws.lambda.demo;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.AnonymousAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Builder;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import io.findify.s3mock.S3Mock;
public class S3Mock {
S3Mock api = new S3Mock.Builder().withPort(8001).withInMemoryBackend().build();
api.start();
AmazonS3Client client = new AmazonS3Client(new AnonymousAWSCredentials());
// use local API mock, not the AWS one
client.setEndpoint("http://127.0.0.1:8001");
client.createBucket("testbucket");
client.putObject("testbucket", "file/name", "contents");
}
But i am not able to compile my class itself .
Can some body help me understand what else i have to do in order to make this work .
I believe you have missed the dependency for S3Mock which comes with below maven:
<dependency>
<groupId>io.findify</groupId>
<artifactId>s3mock_2.12</artifactId>
<version>0.2.5</version>
<scope>test</scope>
</dependency>
Also, I will suggest you rename your class from S3Mock to something like AmazonS3Mock just to avoid namespace confusions

Pact JVM Junit Consumer Compilation Error

I am writing the Consumer Side Code for Pact using JVm-Junit library. However at the line :
MockProviderConfig config = MockProviderConfig.createDefault();
i am getting error "createDefault() is not undefined for the type MockProviderConfig"
What can I do to proceed.
My POM File looks like this :
http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
Consumer_0805
Consumer_080517
0.0.1-SNAPSHOT
war
<dependencies>
<dependency>
<groupId>au.com.dius</groupId>
<artifactId>pact-jvm-consumer-junit_2.11</artifactId>
<version>3.2.9</version>
</dependency>
</dependencies>
Test Code :
package DSLDirectConsumerTest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import au.com.dius.pact.consumer.ConsumerPactBuilder;
import au.com.dius.pact.model.MockProviderConfig;
import au.com.dius.pact.model.MockProviderConfig$;
import au.com.dius.pact.model.PactConfig;
import au.com.dius.pact.model.PactFragment;
import au.com.dius.pact.model.RequestResponsePact;
public class DirectDSLConsumerPactTest {
#Test
public void testPact() {
PactFragment pactFragment = ConsumerPactBuilder.consumer("Some Consumer").hasPactWith("Some Provider")
.uponReceiving("a request to say Hello").path("/hello").method("POST").body("{\"name\": \"harry\"}")
.willRespondWith().status(200).body("{\"hello\": \"harry\"}").toFragment();
MockProviderConfig.createDefault();
}
}
In version 3.3.8, the MockProviderConfig class is a groovy class, so can be accessed normally.
Prior to version 3.3.0, it was both a Scala Singleton Object and Class, so you would need to access it appropriately as per calling Scala classes from Java.
As createDefault() is defined on the companion singleton object, the correct way to refer to it is:
MockProviderConfig$.MODULE$.createDefault();

PowerMock ECLEmma coverage issue

We are using EasyMock and PowerMock with JUnit. The coverage tool used is ECLEmma. With EasyMock, it shows the coverage properly in green (as covered). However, for the code that is unit tested with PowerMock, the coverage is shown in red (uncovered). Have read similar questions on the web. However, just wanted to check if there is a solution for this.
Thanks
Venkatesh
Yes, there is a solution for this:
First you will have to add this maven dependency:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule-agent</artifactId>
<version>1.6.4</version>
<scope>test</scope>
</dependency>
Then, instead of using this annotation #RunWith(PowerMockRunner.class), just add a #Rule in the Test class like this:
public class Test {
#Rule
public PowerMockRule rule = new PowerMockRule();
you can find more in this blog Make EclEmma test coverage work with PowerMock
It's a known problem : https://github.com/jayway/powermock/issues/422
And it has been for a long time, it won't be fixed anytime soon.
I suggest you use eCobertura instead.
This has worked in most cases in my project:
#Rule
public PowerMockRule rule = new PowerMockRule();
static {
PowerMockAgent.initializeIfNeeded();
}
Remove/Comment #RunWith(PowerMockRunner.class) & include following imports after adding powermock-module-javaagent-1.6.5.jar in your classpath:
import org.junit.Rule;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.powermock.modules.agent.PowerMockAgent;
Now right click->Coverage As->Coverage Configurations and add following lines in Arguments:
-ea -noverify -javaagent:path/to/powermock-module-javaagent-1.6.5.jar
Click Apply->Coverage.
Also note that #Before would not work in this case so you have to add all the stuffs in the methods marked with #Test from the method marked with #Before.
We have a static classes to mock. With mocking static classes, eclEmma code coverage plugin is not working in Eclipse. So what we did is, so placed #RunWith(JUnit4.class) (Instead of #RunWith(PowerMockRunner.class) ) before class and placed following lines inside class
static {
PowerMockAgent.initializeIfNeeded();
}
#Rule
public PowerMockRule rule = new PowerMockRule();
Compiled the class and ran the test class. Code coverage is working for class. This change is only in Eclipse IDE.
After writing test cases, we reverted code back to normal. Placed #RunWith(PowerMockRunner.class) instead of #RunWith(JUnit4.class) and commented above static code and powermockrule lines.
I have managed to generate PowerMock coverage with Jacoco, using powermock-module-javaagent.
Just make sure you put powermock agent after jacoco agent:
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>true</useSystemClassLoader>
<argLine>${jacocoArgLine} -javaagent:${settings.localRepository}/org/powermock/powermock-module-javaagent/${powermock.version}/powermock-module-javaagent-${powermock.version}.jar -noverify</argLine>
...
If you want to see an example, take a look at this project: https://github.com/jfcorugedo/sonar-scanner
Here you can see that sonar takes into account static methods and new statements mocked by PowerMock:
If you want to mock newstatements make sure you use PowerMockRule instead of PowerMockRunner.
Take a look at this test
Updating powermock version fix my issue below is maven dependency of supported version
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-rule-agent</artifactId>
<version>1.7.3</version>
<scope>test</scope>
</dependency>
Hope this helps !!!
I was facing the same issue. So, I updated the powerMockito version. Now I am using Power mock version 1.7.4 and Jacoco version 0.8.5. It's even working on eclipse also.
Here is some more detailed answer with full class.
couple of points to note:
I had to use spy instead of mockStatic
I had to move #PrepareForTest to method level.
As someone mentioned in other answers I also had to add following dependency
org.powermock:powermock-module-junit4-rule-agent:2.0.9
Below is my full class code for reference:
import java.util.ArrayList;
import java.util.Arrays;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.IndicesOptions;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.agent.PowerMockAgent;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.opensource.dummy.config.DummyConfig;
import org.opensource.dummy.data.builder.DataBuilder;
import org.opensource.dummy.model.SampleRequest;
import org.opensource.dummy.model.SampleType;
import org.opensource.dummy.model.Item;
import org.opensource.dummy.model.RequestType;
#RunWith(JUnit4.class)
public class MockedDataSearchServiceHelperTest {
static {
PowerMockAgent.initializeIfNeeded();
}
#Rule
public PowerMockRule rule = new PowerMockRule();
#PrepareForTest({ DummyConfig.class })
#SuppressWarnings("unchecked")
#Test
public void testSearchResponseValid() throws Exception {
Item Item = DataBuilder.createItem("2024-01-24", "2024-12-25", "61ef8faebec3bb72fbcf336d", null);
SampleRequest sampleRequest = DataBuilder.createSampleRequest(Arrays.asList(Item),
DataBuilder.createDeliveryMetrics(1), null, RequestType.ITEM);
BoolQueryBuilder boolQueryBuilder = DataSearchServiceHelper.createCustomQuery(sampleRequest, Item);
SearchRequestBuilder searchRequestBuilder = PowerMockito.mock(SearchRequestBuilder.class);
ActionFuture<SearchResponse> actionFuture = PowerMockito.mock(ActionFuture.class);
Client client = PowerMockito.mock(Client.class);
PowerMockito.spy(DummyConfig.class);
PowerMockito.doReturn(client).when(DummyConfig.class, "getClient");
Mockito.when(client
.prepareSearch(new String[] { "dummy" }))
.thenReturn(searchRequestBuilder);
Mockito.when(searchRequestBuilder.setIndicesOptions(IndicesOptions.LENIENT_EXPAND_OPEN))
.thenReturn(searchRequestBuilder);
Mockito.when(searchRequestBuilder.setQuery(Mockito.any(QueryBuilder.class))).thenReturn(searchRequestBuilder);
Mockito.when(searchRequestBuilder.execute()).thenReturn(actionFuture);
Mockito.when(actionFuture.actionGet()).thenReturn(new SearchResponse(null, null, 0, 0, 0, 0, null, null));
SearchResponse searchResponse = DataSearchServiceHelper.getSearchResponse(
new String[] { "dummy" },
boolQueryBuilder, DataBuilder.createDeliveryMetrics(1), RequestType.ITEM);
Assert.assertNotNull(searchResponse);
}
}
I hope this helps to someone.
For mocking static classes, using #RunWith(PowerMockRunner.class) and running the "Coverage As JUnit Test" on Eclipse does show covered code as uncovered and it clearly does seem like an issue.
To add to the solutions above, in a maven project, you can try this..
In the root pom.xml, for report generation, add html as a format in cobertura-maven-plugin. Below is the way it looks.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<configuration>
<formats>
<format>html</format>
<format>xml</format>
</formats>
</configuration>
</plugin>
Then, go to the module where your class resides and open target/site/cobertura/index.html file in Eclipse Web Browser or in the one of your choice. You can find the coverage information there.

Why does Alternator mock DynamoDB fail from maven but not Eclipse?

I have been in touch with the author of Alternator about this issue, and he's as puzzled as I am. The short story: I have written unit tests of code that operates against DynamoDB using the Alternator mocking framework that work fine when I invoke them from within Eclipse, but fail when invoked from maven.
The failure arises from within the AWS SDK itself:
com.amazonaws.AmazonServiceException: [java.lang.Error: property value is null.]
at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:679) ~[aws-java-sdk-1.5.5.jar:na]
at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:350) ~[aws-java-sdk-1.5.5.jar:na]
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:202) ~[aws-java-sdk-1.5.5.jar:na]
at com.michelboudreau.alternatorv2.AlternatorDBClientV2.invoke(AlternatorDBClientV2.java:225) ~[alternator-0.6.4.jar:na]
at com.michelboudreau.alternatorv2.AlternatorDBClientV2.updateItem(AlternatorDBClientV2.java:99) ~[alternator-0.6.4.jar:na]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$2.executeLowLevelRequest(DynamoDBMapper.java:646) ~[aws-java-sdk-1.5.5.jar:na]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper$SaveObjectHandler.execute(DynamoDBMapper.java:767) ~[aws-java-sdk-1.5.5.jar:na]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:658) ~[aws-java-sdk-1.5.5.jar:na]
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.save(DynamoDBMapper.java:488) ~[aws-java-sdk-1.5.5.jar:na]
at com.somoglobal.eventdata.Controller.addDeviceKeys(Controller.java:531) ~[classes/:na]
which as you can see is not hugely useful as the stack trace itself is just showing the stack at the point where the AWS SDK is assembling an exception from the response received through the (mocked) remote service.
The relevant version numbers:
Maven 3.0.4
Java 1.7.0_10
AWS SDK 1.5.5 (although I've also tried 1.5.3 and 1.5.4)
Eclipse version "Kepler", Build id: 20130614-0229
Burrowing down a bit further, the (slightly elided) pom.xml for the project
<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">
<parent>
<groupId>snip</groupId>
<artifactId>snip</artifactId>
<version>1.14.2-SNAPSHOT</version>
</parent>
<artifactId>snip</artifactId>
<version>1.6.0-SNAPSHOT</version>
<name>snip</name>
<dependencies>
...snip...
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk</artifactId>
<version>1.5.5</version>
</dependency>
<dependency>
<groupId>com.michelboudreau</groupId>
<artifactId>alternator</artifactId>
<version>0.6.4</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
and the slightly trimmed down test:
package com.xxx;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.joda.time.DateTime;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
import com.amazonaws.Request;
import com.amazonaws.handlers.RequestHandler;
import com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper;
import com.amazonaws.services.dynamodbv2.model.AttributeDefinition;
import com.amazonaws.services.dynamodbv2.model.CreateTableRequest;
import com.amazonaws.services.dynamodbv2.model.CreateTableResult;
import com.amazonaws.services.dynamodbv2.model.KeySchemaElement;
import com.amazonaws.services.dynamodbv2.model.KeyType;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughputExceededException;
import com.amazonaws.util.TimingInfo;
import com.michelboudreau.alternator.AlternatorDB;
import com.michelboudreau.alternatorv2.AlternatorDBClientV2;
import com.xxx.stuff;
public class ControllerTest {
private static Controller instance;
private static DynamoDBMapper mapper;
private static AlternatorDB db;
private static AlternatorDBClientV2 client;
#BeforeClass
public static void setup() throws Exception {
client = new AlternatorDBClientV2();
mapper = new DynamoDBMapper(client);
db = new AlternatorDB().start();
// code to create dynamodb was here
instance = new Controller(mapper);
}
#AfterClass
public static void tearDown() throws Exception {
db.stop();
}
#Test
public void testAddDeviceKeys() {
Collection<DeviceKey> keys = EventDataModelMapper.getDeviceKeys(ClassFixtures.event);
assertNotNull("keys should not be null", keys);
assertFalse("keys should not be empty", keys.isEmpty());
boolean result = instance.addDeviceKeys(keys);
assertTrue("result should be true", result);
}
}
The code under test is probably not particularly involved in this failure - I've done sufficient debugging tracing to see that it behaves identically during test when invoked directly through Eclipse, and when run from maven.
EDIT
Actually, Alternator might be implicated in this, as the error message in question could be coming out of com.michelboudreau.alternator.validation.ValidatorUtils:
public static <T> List<Error> rejectIfNull(T property) {
List<Error> errors = new ArrayList<Error>();
if (property == null) {
errors.add(new Error("property value is null."));
}
return errors;
}
Ok stand down, Alternator is not at fault, the problem was ultimately between one of the chairs and keyboards at my workplace. The error message in question was indeed arising from Alternator, and ultimately was sourced to a missing table definition - for very complex reasons when the tests were run through Maven there was a discrepancy between the name of the mock Dynamodb table created through Alternator, and the table name that the code under test was trying to access.
I would like to publicly thank Michel Boudreau for taking the time to respond when I contacted him directly on this matter.
Instead you can run Amazon DynamoDB locally.
http://aws.typepad.com/aws/2013/09/dynamodb-local-for-desktop-development.html
Instead, you can run DynamoDB Local using jcabi-dynamodb-maven-plugin (I'm the developer).

Categories

Resources