I need help running a unit test for jsonschema2pojo - java

I have a question regarding unit testing of jsonschema2pojo.
What I am trying to do is use the sample unit test in https://github.com/joelittlejohn/jsonschema2pojo/blob/master/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/json/RealJsonExamplesIT.java
to set up my own test, however I find that there is no test library available. I tried to set up the sources in my project, but I am not using Maven, but Gradle. For the lack of Maven, the class or.jsonschema2pojo.integration.util.JsonSchema2PojoRule class does not want to compile without Maven in my project. In our team we do not use maven in our build server.
I hope that someone can help me point in the direction of how I would unit test my implementation method.
This is the unit test I am trying to run:
public class AnalyticsGeneratorImplTest extends AbstractGoogleAnalyticsTest {
// Set a logger
private static Logger log = LoggerFactory.getLogger(AnalyticsGeneratorImplTest.class);
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
#Rule
public JsonSchema2PojoRule schemaRule = new JsonSchema2PojoRule();
#Test
public void getTitleFromGeneratedJson() throws Exception {
//verify that the incoming Json has been transformed
ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/assets/generated-list/google-analytics.json", "uk.ac.soton.generators.analytics.target",
config("sourceType", "json",
"useLongIntegers", true));
Class<?> googleAnalyticsJsonObject = resultsClassLoader.loadClass("uk.ac.soton.generators.analytics.serialised.GoogleAnalyticsJsonObject");
Object gaJsonObj = OBJECT_MAPPER.readValue(this.getClass().getResourceAsStream("/assets/generated-list/google-analytics.json"), googleAnalyticsJsonObject);
Object result = googleAnalyticsJsonObject.getMethod("getResult").invoke(gaJsonObj);
Object data = result.getClass().getMethod("getData").invoke(result);
Object title = data.getClass().getMethod("getTitle").invoke(data);
assertThat(title.getClass().getMethod("getTitle").invoke(title).toString(), is("blue"));
}
}

You need add the dependecies in gradle:
compile group: 'org.jsonschema2pojo', name: 'jsonschema2pojo-gradle-plugin', version: '0.4.29'
And the others one. If there exist in Maven, it can exist in Gradle too. Check in MavenRepository and select the dependecie you want and Will be exist for all Java Build Toll just select the Gradle Tab and you see the dependecie you need. org.jsonschema2pojo

Related

Cucumber UndefinedStepException when running tests with external runner based on JUnit5 platform

I've written a very simple wrapper around the JUnit5 platform to run tests filtered by my external logics (which feeds path, packageIds, filterFilePath - handling of these was replaced by constant values in code samples to simplify the code snippets).
Here is how the main logic of this wrapper looks like:
public static void main(String[] args) throws JsonProcessingException {
String path = "D:\\repo\\cucumber-java-skeleton\\build\\libs";
String[] packageIds = "io.cucumber.skeleton".split(",");
String filterFilePath = "D:\\repo\\testrunner\\Tests\\Data\\DummyDataProject\\Java\\DummyJavaFilter.json";// contains JSON serialized list of correct test IDs
ClassLoader contextLoader = TestsLoader.GetLoader(path);
Thread.currentThread().setContextClassLoader(contextLoader);
final Launcher launcher = LauncherFactory.create();
List<TestResult> results = new ArrayList<TestResult>();
launcher.execute(getFilteredTestPlan(launcher, filterFilePath),
new TestRunnerExecutionListener(results));
ObjectMapper mapper = new ObjectMapper();
final String jsonResult = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(results);
System.out.print("-==TEST RESULTS START==-");
System.out.print(jsonResult);
System.out.print("-==TEST RESULTS END==-");
}
}
This method returns the TestPlan filtered to IDs which I want to execute (this logics works fine and as expected)
static TestPlan getFilteredTestPlan(Launcher launcher, String filterFilePath) {
String json = new String(Files.readAllBytes(Paths.get(filterFilePath)));
ObjectMapper mapper = new ObjectMapper();
List<String> testIds = mapper.readValue(json, new TypeReference<List<String>>() {});
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(testIds.stream().map(id -> selectUniqueId(id)).toArray(UniqueIdSelector[]::new))
.filters(includeClassNamePatterns(".*")).build();
return launcher.discover(request);
}
So the problem is, that when running this code on a perfectly fine and simple solution like this one provided by #M.P. Korstanje with some additions in gradle.build dependencies section:
testImplementation 'io.cucumber:cucumber-junit-platform-engine:' + cucumberVersion
For junit-platform integration, and these for building proper jar package with discoverable tests:
jar {
from configurations.testCompileClasspath.collect { it.isDirectory() ? it : zipTree(it) }
from sourceSets.test.output
}
The solution itself runs perfectly smooth when step definitions are added and running tests as expected (using default gradle test task). But when running using code provided above - it fails to find step definitions and fails with io.cucumber.junit.platform.engine.UndefinedStepException even though the steps are present. Adding glue property to #CucumberOptions doesn't solve the issue as well (though shouldn't even be needed as step definitions are in the same package).
So I've spent lots of time digging through all available sources without any luck for a few days already, any help will be much appreciated.
I've removed all error handling and section that handles discovery of the tests as irrelevant to the problem, test IDs coming from this code as input are verified correctly.
Update:
When I am adding step definitions into a class contained in the same package which contains executor logics, it successfully discovers it, even though the glue setting points to a totally different package, it seems that these annotations are ignored, as code above discovers tests even when these annotations are removed completely:
#RunWith(Cucumber.class)
#CucumberOptions(plugin = { "pretty" }, glue = "io.cucumber.skeleton")
.
So after some experimentation, I came up with a dirty hack that does the trick:
System.setProperty("cucumber.glue", String.join(",", packageIds));//packageIds has to contain all Step Definitions pacakges
This adds system property that is later on handled by this code as in this documentation stated that it either gets properties file (which I've failed to add into Jar file as I'm pretty new to Java and Jar packaging specifics) or reads system properties in JVM which I have added. A more successful solution would be getting these properties from the target package that contains tests, which I've also failed to do without excessive searches and some pretty heavy reflection usage. The ideal solution is proper integration between the Cucumber Runner and Junit platform which is not yet in place or I've miss-used it somehow. Any better replies will be much appreciated and will be marked as a proper answer.

Cannot mock final Kotlin class using Mockito 2

I am unable to mock a Kotlin final class using Mockito 2. I am using Robolectric in addition.
This is my test code:
#RunWith(RobolectricTestRunner.class)
#Config(constants = BuildConfig.class, sdk = 21)
public class Test {
// more mocks
#Mock
MyKotlinLoader kotlinLoader;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
}
The test fails when we try to initialise the mocks in the setUp() method.
In addition, I am using the following gradle dependencies in my code:
testCompile 'org.robolectric:robolectric:3.3.2'
testCompile 'org.robolectric:shadows-multidex:3.3.2'
testCompile 'org.robolectric:shadows-support-v4:3.3.2'
testCompile("org.powermock:powermock-api-mockito2:1.7.0") {
exclude module: 'hamcrest-core'
exclude module: 'objenesis'
}
testCompile 'junit:junit:4.12'
testCompile 'org.mockito:mockito-inline:2.8.9'
All other unit tests pass using this configuration but as soon as I try to mock the Kotlin class it throws the following error:
Mockito cannot mock/spy because :
- final class
Please note I am using Mockito version 2 and I am using the inline dependency which automatically enables the ability to mock final classes.
PowerMock implements its own MockMaker which leads to incompatibility with Mockito mock-maker-inline, even if PowerMock is just added as a dependency and not used. If two org.mockito.plugins.MockMaker exist in path then any only one can be used, which one is undetermined.
PowerMock can however delegate calls to another MockMaker, and for then tests are run without PowerMock. Since PowerMock 1.7.0 this can be configured with using the PowerMock Configuration.
The MockMaker can be configured by creating the file org/powermock/extensions/configuration.properties and setting:
mockito.mock-maker-class=mock-maker-inline
Example of using Mockito mock-maker-inline with PowerMock: https://github.com/powermock/powermock-examples-maven/tree/master/mockito2
Since Mockito 2.1.0 there is a possibility to mock final types, enums, and final methods. It was already mentioned in the comments to the original question.
To do this, you’ll need to create a folder (if dont exist) test/resources/mockito-extensions and add there file with the name org.mockito.plugins.MockMaker and this line:
mock-maker-inline
Links to documentation and tutorial
mock-maker-inline works as is pointed out in other answers. But It's really slow. You can use the all-open plugin to avoid this problem.
To do so you need:
Create an Annotation:
annotation class Mockable
Activate all-open in your build.gradle file:
dependencies {
classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
}
apply plugin: 'kotlin-allopen'
allOpen {
annotation('com.example.Mockable')
}
Annotate the classes that you want to mock:
#Mockable
class Foo {
fun calculateTheFoo(): Int {
sleep(1_000) // Difficult things here
return 1
}
}
If you want more information you can read my blog post where I explain this with more details: Mocking Kotlin classes with Mockito — the fast way
Try adding this below dependency to your build.gradle.
testImplementation 'org.mockito:mockito-inline:2.8.47'
Replace with your mockito version instead of 2.8.47. This will help you to avoid using powermock for the issue.
please look into the below link to know how this thing works.
How to mock a final class with mockito
You may use Powermock for this, for example:
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.spy;
import static org.powermock.api.mockito.PowerMockito.when;
#RunWith(RobolectricTestRunner.class)
#Config(constants = BuildConfig.class, sdk = 21)
#PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
#PrepareForTest({FinalClass1.class, FinalClass2.class})
public class Test {
#Rule
public PowerMockRule rule = new PowerMockRule();
... // your code here
}
Let us program to interfaces, not implementations. You can extract an interface, use it in your code, and mock it. For example, the following will not work:
import com.nhaarman.mockito_kotlin.mock
class MyFinalClass {...}
(snip)
private val MyFinalClass = mock()
So let us extract an interface:
class MyFinalClass : MyInterface {...}
(snip)
private val MyInterface = mock()
Because in kotlin all classes are final by default.
You should also consider adding open to the class declaration.
Example: open class MyClasss{}

How to add unit tests to Java project in intellij IDEA?

I want to create simple java project with JUnit, so for example I'm want to write an algorithm like merge sort or some Java class and create test class so I can make unit test for that class.
I've create the project with:
File -> New -> Project -> java -> next and setup the project name and
location
and I want to make the unit test for the class the I've created, and I've tried the following solotions :
solution 1 from IntelliJ IDEA dosc using the light bulb to create the test class
solution 2 using shortcut [ctrl + shift + t]
But I always endup with import static org.junit.Assert.*; cannot resolve symbol 'junit', I tried different unit test library end up the same way.
How to resolve this problem so I can make unit test class in this simple Java project?
You can use Gradle or Maven (my personal preference these days).
But the easiest way is to add the JUnit JAR to your project, write some tests, and execute them in IntelliJ.
Go to JUnit and download version 4.12 of the JAR. Put it in a folder /test-lib in your IntelliJ project.
Create a folder /src and add a package /model and a Java class Foo to it (I'll write you one).
Mark /src as a source root.
Create a folder /test and add a package /model and a Java class FooTest to it (I'll write that, too).
Mark /test as a test source root.
Right click on /test and tell IntelliJ to "Run All Tests".
IntelliJ will run all the tests and present the results in the Run window.
Here's the model class:
package model;
public class Foo {
private String value;
public Foo(String v) { this.value = v; }
public String toString() { return this.value; }
}
Here's the test class:
package model;
public class FooTest {
#Test
public void testToString() {
String expected = "Test";
Foo foo = new Foo(expected);
Assert.assertEquals(expected, foo.toString());
}
}
I'm not sure this is the best solutions but I manage to build the unit test use gradle and maven. like this :
create Java project :
File -> New -> Project -> Gradle -> choose only java-> fill the
groupId and ArtifactId-> choose use default gradle wrapper -> enter
project name and location ->finish
and from the root of the project
right click -> Add Framework Support -> choose maven.
from there I can create the class that I want and make the unit test using the solutions from the question [ctrl + shift +t] .

Groovy #Immutable classes in Java

I often recommend Groovy's #Immutable AST transformation as an easy way to make classes, well, immutable. This always works fine with other Groovy classes, but someone recently asked me if I could mix those classes into Java code. I always thought the answer was yes, but I'm hitting a snag.
Say I have an immutable User class:
import groovy.transform.Immutable
#Immutable
class User {
int id
String name
}
If I test this using a JUnit test written in Groovy, everything works as expected:
import org.junit.Test
class UserGroovyTest {
#Test
void testMapConstructor() {
assert new User(name: 'name', id: 3)
}
#Test
void testTupleConstructor() {
assert new User(3, 'name')
}
#Test
void testDefaultConstructor() {
assert new User()
}
#Test(expected = ReadOnlyPropertyException)
void testImmutableName() {
User u = new User(id: 3, name: 'name')
u.name = 'other'
}
}
I can do the same with a JUnit test written in Java:
import static org.junit.Assert.*;
import org.junit.Test;
public class UserJavaTest {
#Test
public void testDefaultCtor() {
assertNotNull(new User());
}
#Test
public void testTupleCtor() {
assertNotNull(new User(3, "name"));
}
#Test
public void testImmutableName() {
User u = new User(3, "name");
// u.setName("other") // Method not found; doesn't compile
}
}
This works, though there are troubles on the horizon. IntelliJ 15 doesn't like the call to new User(), claiming that constructor is not found. That also means the IDE underlines the class in red, meaning it has a compilation error. The test passes anyway, which is a bit strange, but so be it.
If I try to use the User class in Java code directly, things start getting weird.
public class UserDemo {
public static void main(String[] args) {
User user = new User();
System.out.println(user);
}
}
Again IntelliJ isn't happy, but compiles and runs. The output is, of all things:
User(0)
That's odd, because although the #Immutable transform does generate a toString method, I rather expected the output to show both properties. Still, that could be because the name property is null, so it's not included in the output.
If I try to use the tuple constructor:
public class UserDemo {
public static void main(String[] args) {
User user = new User(3, "name");
System.out.println(user);
}
}
I get
User(0, name)
as the output, at least this time (sometimes it doesn't work at all).
Then I added a Gradle build file. If I put the Groovy classes under src\main\groovy and the Java classes under src\main\java (same for the tests but using the test folder instead), I immediately get a compilation issue:
> gradle test
error: cannot find symbol
User user = new User(...)
^
I usually fix cross-compilation issues like this by trying to use the Groovy compiler for everything. If I put both classes under src\main\java, nothing changes, which isn't a big surprise. But if I put both classes under src\main\groovy, then I get this during the compileGroovy phase:
> gradle clean test
error: constructor in class User cannot be applied to the given types;
User user = new User(3, "name");
required: no arguments
found: int,String
reason: actual and formal arguments differ in length
Huh. This time it's objecting to the tuple constructor, because it thinks it only has a default constructor. I know the transform adds a default, a map-based, and a tuple constructor, but maybe they're not being generated in time for the Java code to see them.
Incidentally, if I separate the Java and Groovy classes again, and add the following to my Gradle build:
sourceSets {
main {
java { srcDirs = []}
groovy { srcDir 'src/main/java' }
}
}
I get the same error. If I don't add the sourceSets block, I get the User class not found error from earlier.
So the bottom line is, what's the correct way to add an #Immutable Groovy class to an existing Java system? Is there some way to get the constructors to be generated in time for Java to see them?
I've been making Groovy presentations to Java developers for years and saying you can do this, only to now run into problems. Please help me save face somehow. :)
I did try your scenario as well, where you have a single project with a src/main/java and a src/main/groovy directory and ended up with compilation errors similar to what you saw.
I was able to use Groovy immutable objects in Java when I put the Groovy immutables in a separate project from the Java code. I have created a simple example and pushed it to GitHub (https://github.com/cjstehno/immut).
Basically it's a Gradle multi-project with all the Groovy code (the immutable object) in the immut-groovy sub-project and all the Java code in the immut-java project. The immut-java project depends on the immut-groovy project and uses the immutable Something object:
public class SomethingFactory {
Something createSomething(int id, String label){
return new Something(id, label);
}
}
I added a unit test in the Java project which creates a new instance of the immutable Groovy class and verifies its contents.
public class SomethingFactoryTest {
#Test
public void createSomething(){
Something something = new SomethingFactory().createSomething(42, "wonderful");
assertEquals(something.getId(), 42);
assertEquals(something.getLabel(), "wonderful");
}
}
This is not really ideal, but it works.

How to write tests for API based on Google Cloud Endpoints?

Is there some way to test API written using Google Cloud Endpoint using JUnit or other framework?
In documentation there is an example using curl commands and perhaps the logic behind this is to test API on client side only.
When I tried to find some approaches how to test API from server-side, I came across the possibility of writing JUnit tests and invoking HttpURLConnection's to localhost, but there are problems with this approach. For example, the instance of app engine should be already running before testing, but I deploy locally with maven and testing is prior deploying, so if I have broken tests it doesn't deploy dev server and I do not feel that that is the right way to rewrite maven steps.
Edit 1: Found something similar for Python: How to unit test Google Cloud Endpoints
With Objectify you can do it like this. For example, let's declare our BooksEndpoint as follows:
#Api(
name = "books",
version = "v1",
namespace = #ApiNamespace(ownerDomain = "backend.example.com", ownerName = "backend.example.com", packagePath = "")
)
public class BooksEndpoint {
#ApiMethod(name = "saveBook")
public void saveBook(Book book, User user) throws OAuthRequestException, IOException {
if (user == null) {
throw new OAuthRequestException("User is not authorized");
}
Account account = AccountService.create().getAccount(user);
ofy().save()
.entity(BookRecord.fromBook(account, book))
.now();
}
}
To test it, you would need following dependencies:
testCompile 'com.google.appengine:appengine-api-labs:1.9.8'
testCompile 'com.google.appengine:appengine-api-stubs:1.9.8'
testCompile 'com.google.appengine:appengine-testing:1.9.8'
testCompile 'junit:junit:4.12'
Now, test will look as follows:
public class BooksEndpointTest {
private final LocalServiceTestHelper testHelper = new LocalServiceTestHelper(
new LocalDatastoreServiceTestConfig()
);
private Closeable objectifyService;
#Before
public void setUp() throws Exception {
testHelper.setUp();
objectifyService = ObjectifyService.begin(); // required if you want to use Objectify
}
#After
public void tearDown() throws Exception {
testHelper.tearDown();
objectifyService.close();
}
#Test
public void testSaveBook() throws Exception {
// Create Endpoint and execute your method
new BooksEndpoint().saveBook(
Book.create("id", "name", "author"),
new User("example#example.com", "authDomain")
);
// Check what was written into datastore
BookRecord bookRecord = ofy().load().type(BookRecord.class).first().now();
// Assert that it is correct (simplified)
assertEquals("name", bookRecord.getName());
}
}
Note, I'm using BookRecord and Book here - those are my Entity and POJO, nothing special.
First, thanks for the link to the Python answer. Regarding Java, this Udacity course is based around a Google Cloud Endpoints project in Java, and it has many code examples on how to test endpoints. The source code is here. I have been trying to reproduce the project in Python, and I unfortunately cannot provide any details based on personal experience with testing endpoints written in Java, but I hope the links help!

Categories