How to mock Gson in mockito - java

In my application, there are few REST resources been invoked and I am using Gson as the library for parsing the responses received. While writing unit tests for the above methods I am unable to mock the Gson class as it is a final class.
While doing some research over the internet I found that a file named org.mockito.plugins.MockMaker should be created at src/test/resources/mockito-extensions with the content of the following,
mock-maker-inline
but still am unable to get it worked. What I am doing wrong.
I am getting the following exception when running the above test case (due to the gson object is not being properly mocked)
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
at com.google.gson.Gson.fromJson(Gson.java:803)
at com.google.gson.Gson.fromJson(Gson.java:768)
at com.google.gson.Gson.fromJson(Gson.java:717)
at com.google.gson.Gson.fromJson(Gson.java:689)
at org.kasun.sample.client.supportjira.impl.GroupRestClientImpl.addUser(GroupRestClientImpl.java:104)
at org.kasun.sample.client.GroupRestClientImplTest.addUserToAGroup(GroupRestClientImplTest.java:102
Please find my classes as follows,
Class been tested:
import com.google.gson.Gson;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import org.testing.kasun.client.supportjira.dto.SaveResult;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
public class GroupRestClientImpl{
private Gson gson = new Gson();
#Override
public SaveResult addUser(User user, Group group) {
WebResource resource = client.resource(baseUri + "/" + GROUP_URI_PREFIX + "/user?groupname=" + group.getName());
ClientResponse response = resource.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON)
.post(ClientResponse.class, user);
String jsonText;
if (response.getStatus() != Response.Status.CREATED.getStatusCode()) {
jsonText = response.getEntity(String.class);
JiraError jiraError = gson.fromJson(jsonText, JiraError.class);
throw new JiraException(jiraError.toString());
}
jsonText = response.getEntity(String.class);
SaveResult saveResults = gson.fromJson(jsonText, SaveResult.class);
return saveResults;
}
}
Test Classes:
class TestBase {
static final String JIRA_API_URL = "http://www.jira.com/jira/rest/api/2";
static final String MEDIA_TYPE_JSON = MediaType.APPLICATION_JSON;
#Mock
Client client;
#Mock
WebResource webResource;
#Mock
WebResource.Builder webResourceBuilder;
#Mock
ClientResponse clientResponse;
#Mock
Gson gson;
void setupMocks(Class<?> postPayloadType) {
initMocks(this);
when(client.resource(anyString())).thenReturn(webResource);
when(webResource.accept(anyString())).thenReturn(webResourceBuilder);
when(webResourceBuilder.type(anyString())).thenReturn(webResourceBuilder);
when(webResourceBuilder.get(eq(ClientResponse.class))).thenReturn(clientResponse);
when(webResourceBuilder.post(eq(ClientResponse.class), any(postPayloadType))).thenReturn(clientResponse);
when(clientResponse.getEntity(eq(String.class))).thenReturn("responseText");
}
#AfterMethod
protected void clearMocks() {
reset(client);
reset(webResource);
reset(webResourceBuilder);
reset(clientResponse);
reset(gson);
}
}
public class GroupRestClientImplTest extends TestBase {
private static final String JIRA_GROUP_API_URL = JIRA_API_URL + "/group";
private static final String JIRA_GROUP_MEMBER_API_URL = JIRA_GROUP_API_URL + "/member?groupname=";
private static final String JIRA_GROUP_MEMBER_ADD_API_URL = JIRA_GROUP_API_URL + "/user?groupname=";
private GroupRestClient groupRestClient;
#BeforeMethod
public void initialize() throws URISyntaxException {
super.setupMocks(Group.class);
groupRestClient = new GroupRestClientImpl(new URI(JIRA_API_URL), client);
}
#Test
public void addUserToAGroup() throws URISyntaxException {
when(clientResponse.getStatus()).thenReturn(Response.Status.CREATED.getStatusCode());
when(webResourceBuilder.post(eq(ClientResponse.class), any(User.class))).thenReturn(clientResponse);
SaveResult saveResult = new SaveResult();
when(gson.fromJson(anyString(), isA(SaveResult.class.getClass()))).thenReturn(saveResult);
// when(gson.fromJson(anyString(), eq(SaveResult.class))).thenReturn(saveResult);
User user = new User();
Group group = new Group();
group.setName("group");
SaveResult result = groupRestClient.addUser(user, group);
// Test if the SaveResult is correct.
Assert.assertEquals(result, saveResult);
}

According to Mockito's documentation, this is feature is built around Java 9.
This mock maker has been designed around Java Agent runtime attachment ; this require a compatible JVM, that is part of the JDK (or Java 9 VM).
If you have a version prior to 9, you can:
When running on a non-JDK VM prior to Java 9, it is however possible to manually add the Byte Buddy Java agent jar using the -javaagent parameter upon starting the JVM.

Related

Why have to initialize all variables again in Parameterized JUnitTest although they are intialize in #Before method or at class level

I have one parametrized Junit test in my class. If I initialize all objects used in this test in #Before method they are not accessible in this parametrized Junit test and it throws NUllPointer Exception, due to which I have to initialize all theses objects again in parametrized Junit test. Why is this behavior ?
This is my parametrized Junit test where I have initialize all objects again and even I need to mock them also again.
#ParameterizedTest
#CsvSource({"1,5550,true","1,0,false","0,5550,false"})
public void itemsAvailableValidatorTest(int kioskId, int siteNbr,Boolean expected) throws Exception {
ItemAvailableRequest request = new ItemAvailableRequest();
ItemAvailableRequestValidator itemAvailableRequestValidator = new ItemAvailableRequestValidator();
context = Mockito.mock(ConstraintValidatorContext.class);
builder = Mockito.mock(ConstraintValidatorContext.ConstraintViolationBuilder.class);
Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()))
.thenReturn(builder);
Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()).addConstraintViolation())
.thenReturn(context);
// set ndc and famId
List<String> ndcs = new ArrayList<>();
List<Integer> famIds = new ArrayList<>();
ndcs.add("1234");
famIds.add(1234);
// set goodRequest fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
request.setKioskId(kioskId);
request.setQty(1);
request.setSiteNbr(siteNbr);
request.setRxFillId(null); // call the custom validator method and verify the response
assertEquals(expected, itemAvailableRequestValidator.isValid(request, context));
}
If I initialize the Following objects of this test in #Before method or at class level this test fails and throughs NullPointer Exception
ItemAvailableRequest request = new ItemAvailableRequest();
ItemAvailableRequestValidator itemAvailableRequestValidator = new ItemAvailableRequestValidator();
context = Mockito.mock(ConstraintValidatorContext.class);
builder = Mockito.mock(ConstraintValidatorContext.ConstraintViolationBuilder.class);
Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()))
.thenReturn(builder);
Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()).addConstraintViolation())
.thenReturn(context);
Why the objects initialized in Before method or at class level are not accessible in #parametrized JunitTest ? and why they need to be specifically initialized inside #paramterized Junit test curly brackets.
Here is the code for whole class
package com.walmart.rxkioskinventory.validator;
import com.walmart.rxkioskinventory.model.request.ItemAvailableRequest;
import com.walmart.rxkioskinventory.model.validator.ItemAvailableRequestValidator;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BeanPropertyBindingResult;
import org.springframework.validation.Errors;
import javax.validation.ConstraintValidatorContext;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class ItemAvailableRequestValidatorTest {
#InjectMocks
ItemAvailableRequestValidator itemAvailableRequestValidator;
private ItemAvailableRequest request;
private ConstraintValidatorContext context;
private ConstraintValidatorContext.ConstraintViolationBuilder builder;
/*
good request initializer
*/
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
// mock the context
context = Mockito.mock(ConstraintValidatorContext.class);
context = Mockito.mock(ConstraintValidatorContext.class);
builder = Mockito.mock(ConstraintValidatorContext.ConstraintViolationBuilder.class);
// context.buildConstraintViolationWithTemplate returns
// ConstraintValidatorContext.ConstraintViolationBuilder
// so we mock that too as you will be calling one of it's methods
builder = Mockito.mock(ConstraintValidatorContext.ConstraintViolationBuilder.class);
// when the context.buildConstraintViolationWithTemplate is called,
// the mock should return the builder.
Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()))
.thenReturn(builder);
Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()).addConstraintViolation())
.thenReturn(context);
request = new ItemAvailableRequest();
// set ndc and famId
List<String> ndcs = new ArrayList<>();
List<Integer> famIds = new ArrayList<>();
ndcs.add("1234");
famIds.add(1234);
// set goodRequest fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
// error for binding the request
Errors errors = new BeanPropertyBindingResult(request, "request");
}
/*
test to verify the valid request with all valid request params
*/
#Test
public void itemsAvailableValidatorSuccessTest() throws Exception {
ItemAvailableRequest request = new ItemAvailableRequest();
// set ndc and famId
List<String> ndcs = new ArrayList<>();
List<Integer> famIds = new ArrayList<>();
ndcs.add("1234");
famIds.add(1234);
// set goodRequest fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
request.setKioskId(1);
request.setQty(1);
request.setSiteNbr(5550);
request.setRxFillId(1);
// call the custom validator method and verify the response
assertEquals(true, itemAvailableRequestValidator.isValid(request, context));
}
/**
*Test to verify response when request is null
*/
#Test
public void itemsAvailableValidatorNullRequestTest() {
ItemAvailableRequest request = null;
// call the custom validator method and verify the response
assertEquals(false, itemAvailableRequestValidator.isValid(request, context));
}
/**
*Test to verify response when quantity is invalid.
*/
#Test
public void itemsAvailableValidatorInvalidQuantityTest() {
ItemAvailableRequest request = new ItemAvailableRequest();
// set ndc and famId
List<String> ndcs = new ArrayList<>();
List<Integer> famIds = null;
ndcs.add("1234");
// set goodRequest fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
request.setKioskId(1);
request.setQty(0.5);
request.setSiteNbr(5550);
request.setRxFillId(null);
// call the custom validator method and verify the response
assertEquals(false, itemAvailableRequestValidator.isValid(request, context));
}
/**
* Test to verify response when SiteNbr is invalid
* #param kioskId it depicts kiosk id
* #param siteNbr it depicts site nbr
* #throws Exception it throws exception
*/
#ParameterizedTest
#CsvSource({"1,5550,true","1,0,false","0,5550,false"})
public void itemsAvailableValidatorTest(int kioskId, int siteNbr,Boolean expected) throws Exception {
ItemAvailableRequest request = new ItemAvailableRequest();
ItemAvailableRequestValidator itemAvailableRequestValidator = new ItemAvailableRequestValidator();
context = Mockito.mock(ConstraintValidatorContext.class);
builder = Mockito.mock(ConstraintValidatorContext.ConstraintViolationBuilder.class);
Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()))
.thenReturn(builder);
Mockito.when(context.buildConstraintViolationWithTemplate(Mockito.anyString()).addConstraintViolation())
.thenReturn(context);
// set ndc and famId
List<String> ndcs = new ArrayList<>();
List<Integer> famIds = new ArrayList<>();
ndcs.add("1234");
famIds.add(1234);
// set goodRequest fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
request.setKioskId(kioskId);
request.setQty(1);
request.setSiteNbr(siteNbr);
request.setRxFillId(null); // call the custom validator method and verify the response
assertEquals(expected, itemAvailableRequestValidator.isValid(request, context));
}
/*
test to verify that if rxFillId is 0 then request is not valid
*/
#Test
public void itemsAvailableValidatorFillIdZeroFailureTest() throws Exception {
ItemAvailableRequest request = new ItemAvailableRequest();
// set ndc and famId
List<String> ndcs = new ArrayList<>();
List<Integer> famIds = new ArrayList<>();
ndcs.add("1234");
famIds.add(1234);
// set goodRequest fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
request.setKioskId(1);
request.setQty(1);
request.setSiteNbr(5550);
request.setRxFillId(0);
// call the custom validator method and verify the response
assertEquals(false, itemAvailableRequestValidator.isValid(request, context));
}
/*
test to verify the valid request with ndc null and required famId
*/
#Test
public void ItemsAvailableValidatorNullNdcSuccessTest() throws Exception {
ItemAvailableRequest request = new ItemAvailableRequest();
// set ndc and famId
List<String> ndcs = null;
List<Integer> famIds = new ArrayList<>();
famIds.add(1234);
// set fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
request.setQty(1);
request.setSiteNbr(5550);
request.setKioskId(5550);
// call the custom validator method and verify the response
assertTrue(itemAvailableRequestValidator.isValid(request, context));
}
/*
test to verify the fail request with params to be null
*/
#Test
public void itemsAvailableValidatorNullFailureTest() throws Exception {
ItemAvailableRequest request = new ItemAvailableRequest();
// set ndc and famId
List<String> ndcs = null;
List<Integer> famIds = null;
// set goodRequest fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
// call the custom validator method and verify the response
assertEquals(false, itemAvailableRequestValidator.isValid(request, context));
}
/*
test to verify the valid request with empty ndc and valid famId
*/
#Test
public void itemsAvailableValidatorEmptyNdcSuccessTest() throws Exception {
ItemAvailableRequest request = new ItemAvailableRequest();
// set ndc and famId
List<String> ndcs = new ArrayList<>();
List<Integer> famIds = new ArrayList<>();
famIds.add(1234);
request.setQty(1);
request.setSiteNbr(5550);
request.setKioskId(5550);
// set goodRequest fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
// call the custom validator method and verify the response
assertTrue(itemAvailableRequestValidator.isValid(request, context));
}
/*
test to verify the fail request with all params to be empty
*/
#Test
public void ItemsAvailableValidatorEmptyFailureTest() throws Exception {
ItemAvailableRequest request = new ItemAvailableRequest();
// set ndc gpi and famId
List<String> ndcs = new ArrayList<>();
List<Integer> famIds = new ArrayList<>();
// set goodRequest fields
request.setNdc(ndcs);
request.setMdsFamId(famIds);
// call the custom validator method and verify the response
assertEquals(false, itemAvailableRequestValidator.isValid(request, context));
}
}
You are mixing JUnit 4 org.junit.Before;, org.junit.Test and JUnit 5 org.junit.jupiter.*. This is causing the problems that you have.
#ParameterizedTest is from JUnit 5. So I suggest to use #BeforeEach and #BeforeAll and org.junit.jupiter.api.Test for #Test. Basically, drop all JUnit imports that are NOT org.junit.jupiter.* including the org.junit.Assert.*.
Here is one example that works with JUnit 5 and it uses #BeforeAll, #ParameterizedTest, #MethodSource, and #Test
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.stream.Stream;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
#TestInstance(TestInstance.Lifecycle.PER_CLASS)
class ParameterizedExampleTest {
private final static String workgroup = "reporting";
private final static String region = "eu-central-1";
private final static String credentialsProviderArguments = "reporting";
private Values values;
private static Stream<Arguments> credentialProvidersWithCorrectArguments() {
String webTokenProvider = "com.amazonaws.auth.WebIdentityTokenCredentialsProvider";
String profileProvider = "com.amazonaws.auth.profile.ProfileCredentialsProvider";
return Stream.of(
Arguments.of(
webTokenProvider,
"jdbc:awsathena://AwsRegion=" + region + ";AwsCredentialsProviderClass=" + webTokenProvider + ";" +
"Workgroup=" + workgroup + ";LogLevel=6;"
),
Arguments.of(
profileProvider,
"jdbc:awsathena://AwsRegion=" + region + ";AwsCredentialsProviderClass=" + profileProvider + ";" +
"AwsCredentialsProviderArguments=" + credentialsProviderArguments + ";Workgroup=" + workgroup +
";LogLevel=6;"
)
);
}
#BeforeAll
public void setup() {
values = new Values();
values.setAthenaRegion(region);
values.setWorkgroup(workgroup);
values.setDebugEnabled(true);
values.setCredentialsProviderArguments(credentialsProviderArguments);
}
#ParameterizedTest
#MethodSource("credentialProvidersWithCorrectArguments")
void credentialsProviderHasCorrectCredentialsArguments(String credentialsProviderClass, String expected) {
values.setCredentialsProviderClass(credentialsProviderClass);
assertEquals(expected, values.getJdbcUrl());
}
#Test
void wrongProviderClassThrowsException() {
String credentialsProviderClass = "com.amazonaws.auth.WrongCredentialsProvider";
values.setCredentialsProviderClass(credentialsProviderClass);
try {
values.getJdbcUrl();
fail("An exception should be thrown to this method.");
} catch (Exception e) {
assertTrue(e.getMessage().contains("AWS credential class does not exist"));
}
}
}
Class being tested:
public class Values {
private String athenaRegion;
private String credentialsProviderClass;
private String credentialsProviderArguments;
private String jdbcDriverClass;
private String databaseSchema;
private String workgroup;
private boolean debugEnabled;
public String getJdbcUrl() {
String athenaJdbcUrl = "jdbc:awsathena://AwsRegion=" + athenaRegion +
";AwsCredentialsProviderClass=" + credentialsProviderClass +
(isProfileCredentialsProvider() ? ";AwsCredentialsProviderArguments=" + credentialsProviderArguments : "") +
";Workgroup=" + workgroup +
(debugEnabled ? ";LogLevel=6;" : ";");
LOG.debug("Athena connection URL: {}", athenaJdbcUrl);
return athenaJdbcUrl;
}
private boolean isProfileCredentialsProvider() {
try {
return (Class.forName(credentialsProviderClass).isAssignableFrom(ProfileCredentialsProvider.class));
} catch (ClassNotFoundException e) {
throw new Exception("AWS credential class does not exist", e);
}
}
// add GETTERS AND SETTERS ...
}

How to create the version and get the details of any version of specific project using JIRA REST CLIENT JAVA in groovy?

I am trying to create the version in JIRA for specific project.Below is my code.I am able to connect the JIRA successfully through JIRA REST CLIENT JAVA java libraries but now want to achieve the get the information of any version,createversion few more actions.
import com.atlassian.jira.rest.client.api.JiraRestClient
import com.atlassian.jira.rest.client.api.JiraRestClientFactory
//import com.atlassian.jira.rest.client.api.domain.User
import com.atlassian.jira.rest.client.api.domain.Version
//import com.atlassian.jira.rest.client.api.domain.input.VersionInput
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory
import com.atlassian.util.concurrent.Promise
class Jira {
private static final String JIRA_URL = "https://jira.test.com"
private static final String JIRA_ADMIN_USERNAME = "ABCDE"
private static final String JIRA_ADMIN_PASSWORD = "xxxxxx"
static void main(String[] args) throws Exception
{
// Construct the JRJC client
System.out.println(String.format("Logging in to %s with username '%s' and password '%s'", JIRA_URL, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD))
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory()
URI uri = new URI(JIRA_URL)
JiraRestClient client = factory.createWithBasicHttpAuthentication(uri, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD)
// client.withCloseable {
// it.projectClient.getProject("ABCD").claim().versions.each { println it }
// }
// Invoke the JRJC Client
//Promise<User> promise = client.getUserClient().getUser(JIRA_ADMIN_USERNAME)
//User user = promise.claim()
Promise<Version> promise = client.getVersionRestClient().getVersion(1234)
//Version version = promise.claim()
// Print the result
System.out.println(String.format("Your user's email address is: %s\r\n", user.getEmailAddress()))
}
}
I am able to do some task like to get the email address of any userid.I am trying this in groovy
package com.temp.jira
import com.atlassian.jira.rest.client.api.JiraRestClient
import com.atlassian.jira.rest.client.api.JiraRestClientFactory
import com.atlassian.jira.rest.client.api.domain.BasicProject
import com.atlassian.jira.rest.client.api.domain.Issue
import com.atlassian.jira.rest.client.api.domain.SearchResult
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory
import com.atlassian.util.concurrent.Promise
/**
* Created on 7/21/2017.
*/
class Test {
private static final String JIRA_URL = "https://jira.test.com"
private static final String JIRA_ADMIN_USERNAME = "ABCDEF"
private static final String JIRA_ADMIN_PASSWORD = "*****"
private static final String JIRA_PROJECT = "ABCD"
static void main(String[] args) throws Exception
{
// Construct the JRJC client
System.out.println(String.format("Logging in to %s with username '%s' and password '%s'", JIRA_URL, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD))
JiraRestClientFactory factory = new AsynchronousJiraRestClientFactory()
URI uri = new URI(JIRA_URL)
JiraRestClient client = factory.createWithBasicHttpAuthentication(uri, JIRA_ADMIN_USERNAME, JIRA_ADMIN_PASSWORD)
for (BasicProject project : client.getProjectClient().getProject(JIRA_PROJECT).claim()) {
System.out.println(project.getKey() + ": " + project.getName())
}
Promise<SearchResult> searchJqlPromise = client.getSearchClient().searchJql("project = $JIRA_PROJECT AND status in (Closed, Completed, Resolved) ORDER BY assignee, resolutiondate");
for (Issue issue : searchJqlPromise.claim().getIssues()) {
System.out.println(issue.getId())
}
// Done
System.out.println("Example complete. Now exiting.")
System.exit(0)
}
}
Stick to the jira rest client api, since you have a typed access provided from the creator o fJira.
Excerpt from my working Groovy code:
/**
* Retrieves the latest unreleased version for the given project.
* #param projectId Given project
* #return latest unreleased version
*/
private Version getVersion(String projectId)
{
def project = restClient.projectClient.getProject(projectId).claim()
def unreleasedVersions = project
.getVersions()
.findAll { version ->
version.released == false
}
if (unreleasedVersions.size() != 1) {
throw new RuntimeException('There are zero or more unreleased versions.')
}
unreleasedVersions.get(0)
}
/**
* Creates a new, undeployed version for the given project.
* #param projectId Given project
*/
private void createVersion(String projectId)
{
def versionInputBuilder = new VersionInputBuilder(projectId)
versionInputBuilder.released = false
versionInputBuilder.name = incrementVersion(capturedVersion.name)
versionInputBuilder.description = 'Bugfixing'
versionInputBuilder.startDate = DateTime.now()
def promise = restClient.versionRestClient.createVersion(versionInputBuilder.build())
trackCompletion(promise)
}
What I don't have in my code is get a certain version, but your commented code should work when you change the data type of the version to string.
I created the script in below way and able to create,update and delete the version
import com.atlassian.jira.rest.client.api.JiraRestClient
import com.atlassian.jira.rest.client.api.VersionRestClient
import com.atlassian.jira.rest.client.api.domain.Version
import com.atlassian.jira.rest.client.api.domain.input.VersionInput
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory
import com.atlassian.util.concurrent.Promise
import org.codehaus.jettison.json.JSONException
import org.joda.time.DateTime
import java.util.concurrent.ExecutionException
class VersionClient {
private static final String JIRA_URL = "https://jira.test.com"
private static final String JIRA_ADMIN_USERNAME = "ABCDEF"
private static final String JIRA_ADMIN_PASSWORD = "******"
private static final String JIRA_PROJECT = "TEST"
static void main(String[] args)
throws URISyntaxException, InterruptedException, ExecutionException, JSONException {
// Initialize REST Client
final AsynchronousJiraRestClientFactory factory = new AsynchronousJiraRestClientFactory()
final URI uri = new URI("$JIRA_URL")
final JiraRestClient jiraRestClient = factory.createWithBasicHttpAuthentication(uri, "$JIRA_ADMIN_USERNAME", "$JIRA_ADMIN_PASSWORD")
// Get specific client instances
VersionRestClient versionClient = jiraRestClient.getVersionRestClient()
// Create Version
VersionInput versionInput = new VersionInput("$JIRA_PROJECT", "TEST 1.2.8", "Test Version", new DateTime(), false, false)
Promise<Version> version = versionClient.createVersion(versionInput)
Version versionObj = version.get()
System.out.println("Created Version:" + versionObj.getName())
// Invoke the JRJC Client
Promise<Version> promise = versionClient.getVersion(versionObj.getSelf())
Version versionid = promise.claim()
// Print the result
System.out.println(String.format("Version id is: %s\r\n", versionid.getId() + " and URI:" + versionid.getSelf()))
// Release Version using Update
versionClient.updateVersion(versionid.getSelf(),new VersionInput("$JIRA_PROJECT", "TEST 1.2.8", "Test Version", new DateTime(), false, true))
// Delete the Version
versionClient.removeVersion(versionid.getSelf(), null, null).claim()
System.out.println("Deleted Version")
}
}

How to resolve a custom option in a protocol buffer FileDescriptor

I'm using protocol buffers 2.5 with Java. I have a proto file that defines a custom option. Another proto file uses that custom option. If I persist the corresponding FileDescriptorProto's and then read them and convert them to FileDescriptors, the reference to the custom option is manifested as unknown field. How do I cause that custom option to be resolved correctly?
Here's the code. I have two .proto files. protobuf-options.proto looks like this:
package options;
import "google/protobuf/descriptor.proto";
option java_package = "com.example.proto";
option java_outer_classname = "Options";
extend google.protobuf.FieldOptions {
optional bool scrub = 50000;
}
The imported google/protobuf/descriptor.proto is exactly the descriptor.proto that ships with Protocol Buffers 2.5.
example.proto looks like this:
package example;
option java_package = "com.example.protos";
option java_outer_classname = "ExampleProtos";
option optimize_for = SPEED;
option java_generic_services = false;
import "protobuf-options.proto";
message M {
optional int32 field1 = 1;
optional string field2 = 2 [(options.scrub) = true];
}
As you can see, field2 references the custom option defined by protobuf-options.proto.
The following code writes a binary-encoded version of all three protos to /tmp:
package com.example;
import com.google.protobuf.ByteString;
import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.example.protos.ExampleProtos;
import java.io.FileOutputStream;
import java.io.OutputStream;
/**
*
*/
public class PersistFDs {
public void persist(final FileDescriptor fileDescriptor) throws Exception {
System.out.println("persisting "+fileDescriptor.getName());
try (final OutputStream outputStream = new FileOutputStream("/tmp/"+fileDescriptor.getName())) {
final FileDescriptorProto fileDescriptorProto = fileDescriptor.toProto();
final ByteString byteString = fileDescriptorProto.toByteString();
byteString.writeTo(outputStream);
}
for (final FileDescriptor dependency : fileDescriptor.getDependencies()) {
persist(dependency);
}
}
public static void main(String[] args) throws Exception {
final PersistFDs self = new PersistFDs();
self.persist(ExampleProtos.getDescriptor());
}
}
Finally, the following code loads those those protos from /tmp, converts them back into FileDescriptors, and then checks for the custom option on field2:
package com.example;
import com.google.protobuf.ByteString;
import com.google.protobuf.DescriptorProtos.FileDescriptorProto;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.UnknownFieldSet.Field;
import java.io.FileInputStream;
import java.io.InputStream;
/**
*
*/
public class LoadFDs {
public FileDescriptorProto loadProto(final String filePath) throws Exception {
try (final InputStream inputStream = new FileInputStream(filePath)) {
final ByteString byteString = ByteString.readFrom(inputStream);
final FileDescriptorProto result = FileDescriptorProto.parseFrom(byteString);
return result;
}
}
public static void main(final String[] args) throws Exception {
final LoadFDs self = new LoadFDs();
final FileDescriptorProto descriptorFDProto = self.loadProto("/tmp/google/protobuf/descriptor.proto");
final FileDescriptorProto optionsFDProto = self.loadProto("/tmp/protobuf-options.proto");
final FileDescriptorProto fakeBoxcarFDProto = self.loadProto("/tmp/example.proto");
final FileDescriptor fD = FileDescriptor.buildFrom(descriptorFDProto, new FileDescriptor[0]);
final FileDescriptor optionsFD = FileDescriptor.buildFrom(optionsFDProto, new FileDescriptor[] { fD });
final FileDescriptor fakeBoxcarFD = FileDescriptor.buildFrom(fakeBoxcarFDProto, new FileDescriptor[] { optionsFD });
final FieldDescriptor optionsFieldDescriptor = optionsFD.findExtensionByName("scrub");
if (optionsFieldDescriptor == null) {
System.out.println("Did not find scrub's FieldDescriptor");
System.exit(1);
}
final FieldDescriptor sFieldDescriptor = fakeBoxcarFD.findMessageTypeByName("M").findFieldByName("field2");
System.out.println("unknown option fields "+sFieldDescriptor.getOptions().getUnknownFields());
final boolean hasScrubOption = sFieldDescriptor.getOptions().hasField(optionsFieldDescriptor);
System.out.println("hasScrubOption: "+hasScrubOption);
}
}
When I run LoadFDs, it fails with this exception:
unknown option fields 50000: 1
Exception in thread "main" java.lang.IllegalArgumentException: FieldDescriptor does not match message type.
at com.google.protobuf.GeneratedMessage$ExtendableMessage.verifyContainingType(GeneratedMessage.java:812)
at com.google.protobuf.GeneratedMessage$ExtendableMessage.hasField(GeneratedMessage.java:761)
at com.example.LoadFDs.main(LoadFDs.java:42)
The options for FieldDescriptor for the s field ought to have a field for that custom option, but instead it has an unknown field. The field number and value on the unknown field are correct. It's just that the custom option is not getting resolved. How do I fix that?
You need to use FileDescriptorProto.parseFrom(byte[] data, ExtensionRegistryLite extensionRegistry, and explicitly create an ExtentionRegistry. Here's one way to create an extension registry:
ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
com.example.proto.Options.registerAllExtensions(extensionRegistry);
(where com.example.proto.Options is the compiled custom options class)
This obviously only works if you have access to the custom options compiled file on client side. I don't know if there's a way to serialize the extension and deserialize it on the client side.

Java: Simple HTTP Server application that responds in JSON

I want to create a very simple HTTP server application in Java.
For example, if I run the server on localhost in port 8080, and I make to following call from my browser, I want to get a Json array with the string 'hello world!':
http://localhost:8080/func1?param1=123&param2=456
I would like to have in the server something that looks like this (very abstract code):
// Retunrs JSON String
String func1(String param1, String param2) {
// Do Something with the params
String jsonFormattedResponse = "['hello world!']";
return jsonFormattedResponse;
}
I guess that this function should not actually "return" the json, but to send it using some HTTP response handler or something similar...
What it the simplest way to do it, without a need to get familiar with many kinds of 3rd party libraries that have special features and methodology?
You could use classes from the package com.sun.net.httpserver:
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class JsonServer {
private static final String HOSTNAME = "localhost";
private static final int PORT = 8080;
private static final int BACKLOG = 1;
private static final String HEADER_ALLOW = "Allow";
private static final String HEADER_CONTENT_TYPE = "Content-Type";
private static final Charset CHARSET = StandardCharsets.UTF_8;
private static final int STATUS_OK = 200;
private static final int STATUS_METHOD_NOT_ALLOWED = 405;
private static final int NO_RESPONSE_LENGTH = -1;
private static final String METHOD_GET = "GET";
private static final String METHOD_OPTIONS = "OPTIONS";
private static final String ALLOWED_METHODS = METHOD_GET + "," + METHOD_OPTIONS;
public static void main(final String... args) throws IOException {
final HttpServer server = HttpServer.create(new InetSocketAddress(HOSTNAME, PORT), BACKLOG);
server.createContext("/func1", he -> {
try {
final Headers headers = he.getResponseHeaders();
final String requestMethod = he.getRequestMethod().toUpperCase();
switch (requestMethod) {
case METHOD_GET:
final Map<String, List<String>> requestParameters = getRequestParameters(he.getRequestURI());
// do something with the request parameters
final String responseBody = "['hello world!']";
headers.set(HEADER_CONTENT_TYPE, String.format("application/json; charset=%s", CHARSET));
final byte[] rawResponseBody = responseBody.getBytes(CHARSET);
he.sendResponseHeaders(STATUS_OK, rawResponseBody.length);
he.getResponseBody().write(rawResponseBody);
break;
case METHOD_OPTIONS:
headers.set(HEADER_ALLOW, ALLOWED_METHODS);
he.sendResponseHeaders(STATUS_OK, NO_RESPONSE_LENGTH);
break;
default:
headers.set(HEADER_ALLOW, ALLOWED_METHODS);
he.sendResponseHeaders(STATUS_METHOD_NOT_ALLOWED, NO_RESPONSE_LENGTH);
break;
}
} finally {
he.close();
}
});
server.start();
}
private static Map<String, List<String>> getRequestParameters(final URI requestUri) {
final Map<String, List<String>> requestParameters = new LinkedHashMap<>();
final String requestQuery = requestUri.getRawQuery();
if (requestQuery != null) {
final String[] rawRequestParameters = requestQuery.split("[&;]", -1);
for (final String rawRequestParameter : rawRequestParameters) {
final String[] requestParameter = rawRequestParameter.split("=", 2);
final String requestParameterName = decodeUrlComponent(requestParameter[0]);
requestParameters.putIfAbsent(requestParameterName, new ArrayList<>());
final String requestParameterValue = requestParameter.length > 1 ? decodeUrlComponent(requestParameter[1]) : null;
requestParameters.get(requestParameterName).add(requestParameterValue);
}
}
return requestParameters;
}
private static String decodeUrlComponent(final String urlComponent) {
try {
return URLDecoder.decode(urlComponent, CHARSET.name());
} catch (final UnsupportedEncodingException ex) {
throw new InternalError(ex);
}
}
}
On a side note, ['hello world!'] is invalid JSON. Strings must be enclosed in double quotes.
You could :
Install Apache Tomcat, and just drop a JSP into the ROOT project that implements this.
I second #xehpuk. It's not actually that hard to write your own single class HTTP server using just standard Java. If you want to do it in earlier versions you can use NanoHTTPD, which is a pretty well known single class HTTP server implementation.
I would personally recommend that you look into Apache Sling (pretty much THE Reference implementation of a Java REST api). You could probably implement your requirements here using Sling without ANY programming at all.
But as others have suggested, the standard way to do this is to create a java WAR and deploy it into a 'servlet container' such as Tomcat or Jetty etc.
If you are already familiar with servlet you do not need much to create a simple server to achieve what you want. But I would like to emphasize that your needs will likely to increase rapidly and therefore you may need to move to a RESTful framework (e.g.: Spring WS, Apache CXF) down the road.
You need to register URIs and get parameters using the standard servlet technology. Maybe you can start here: http://docs.oracle.com/cd/E13222_01/wls/docs92/webapp/configureservlet.html
Next, you need a JSON provider and serialize (aka marshall) it in JSON format. I recommend JACKSON. Take a look at this tutorial:
http://www.sivalabs.in/2011/03/json-processing-using-jackson-java-json.html
Finally, your code will look similar to this:
public class Func1Servlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String p1 = req.getParameter("param1");
String p2 = req.getParameter("param2");
// Do Something with the params
ResponseJSON resultJSON = new ResponseJSON();
resultJSON.setProperty1(yourPropert1);
resultJSON.setProperty2(yourPropert2);
// Convert your JSON object into JSON string
Writer strWriter = new StringWriter();
mapper.writeValue(strWriter, resultJSON);
String resultString = strWriter.toString();
resp.setContentType("application/json");
out.println(resultString );
}
}
Map URLs in your web.xml:
<servlet>
<servlet-name>func1Servlet</servlet-name>
<servlet-class>myservlets.func1servlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>func1Servlet</servlet-name>
<url-pattern>/func1/*</url-pattern>
</servlet-mapping>
Keep in mind this is a pseudo-code. There are lots you can do to enhance it, adding some utility classes, etc...
Nevertheless, as your project grows your need for a more comprehensive framework becomes more evident.
Run main to start the server on port 8080
public class Main {
public static void main(String[] args) throws LifecycleException {
Tomcat tomcat = new Tomcat();
Context context = tomcat.addContext("", null);
Tomcat.addServlet(context, "func1", new HttpServlet() {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
Object response = func1(req.getParameter("param1"), req.getParameter("param2"));
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(resp.getWriter(), response);
}
});
context.addServletMappingDecoded("/func1", "func1");
tomcat.start();
tomcat.getServer().await();
}
private static String[] func1(String p1, String p2) {
return new String[] { "hello world", p1, p2 };
}
}
Gradle dependencies:
dependencies {
compile group: 'org.apache.tomcat.embed', name: 'tomcat-embed-core', version: '8.5.28' // doesn't work with tomcat 9
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.4'
}

How to mock local variables using mockito or powermock

I have scenario like this
InputStreamReader reader = new InputStreamReader(getFileAsStream(resourceResolver, iconpath));
BufferedReader bReader = new BufferedReader(reader);
I have mocked till this point
getFileAsStream(resourceResolver, iconpath)
now I am getting one reader
BufferedReader bReader = new BufferedReader(reader);
but when I execute this line I get null and not able to move forward
while ((iconEntry = bReader.readLine()) != null)
Please tell me how can I mock this.
Please note I cannot change my main code therefore the solution present on Mockito docs is not valid in my case
Test code
#RunWith(PowerMockRunner.class)
#PrepareForTest({ FrameworkUtil.class, LoggerFactory.class })
public class IconPreviewServletTest {
private IconPreviewServlet iconPreviewServlet;
private SlingHttpServletRequest request;
private SlingHttpServletResponse response;
private Bundle bundle;
private BundleContext bundleContext;
private ServiceReference factoryRef;
private CommonService resolverFactory;
private PrintWriter out;
private ResourceResolver resourceResolver;
private Resource resource;
private Node node;
private Node jcrContent;
private javax.jcr.Property property;
private Binary binary;
private InputStream stream;
private InputStreamReader inputReader;
private BufferedReader reader;
#Before
public void setUp() throws IOException, PathNotFoundException,
RepositoryException {
init();
}
private void init() throws IOException, PathNotFoundException,
RepositoryException {
request = mock(SlingHttpServletRequest.class);
response = mock(SlingHttpServletResponse.class);
bundleContext = mock(BundleContext.class);
factoryRef = mock(ServiceReference.class);
resolverFactory = mock(CommonService.class);
out = mock(PrintWriter.class);
resourceResolver = mock(ResourceResolver.class);
resource = mock(Resource.class);
node = mock(Node.class);
jcrContent = mock(Node.class);
property = mock(Property.class);
binary = mock(Binary.class);
stream=IOUtils.toInputStream("some test data for my input stream");
reader = mock(BufferedReader.class);
inputReader=mock(InputStreamReader.class);
bundle = mock(Bundle.class);
mockStatic(FrameworkUtil.class);
mockStatic(LoggerFactory.class);
Logger log = mock(Logger.class);
when(LoggerFactory.getLogger(IconPreviewServlet.class)).thenReturn(log);
when(FrameworkUtil.getBundle(CommonService.class)).thenReturn(bundle);
when(bundle.getBundleContext()).thenReturn(bundleContext);
when(bundleContext.getServiceReference(CommonService.class.getName()))
.thenReturn(factoryRef);
when(bundleContext.getService(factoryRef)).thenReturn(resolverFactory);
when(request.getParameter("category")).thenReturn("category");
when(request.getParameter("query")).thenReturn("query");
when(response.getWriter()).thenReturn(out);
when(request.getResourceResolver()).thenReturn(resourceResolver);
when(
resourceResolver
.getResource("/etc/designs/resmed/icons/category/icons.txt"))
.thenReturn(resource);
when(resource.adaptTo(Node.class)).thenReturn(node);
when(node.getNode("jcr:content")).thenReturn(jcrContent);
when(jcrContent.getProperty("jcr:data")).thenReturn(property);
when(property.getBinary()).thenReturn(binary);
when(binary.getStream()).thenReturn(stream);
}
To make this work, you need to use Powermockito to intercept the constructor calls (new InputStreamReader(...), new BufferedReader(...)) so that your mocks get returned. An example is below. In your case, just intercepting the new BufferedReader call may be enough.
Assume the following is the code you want to test:
package test;
import java.io.*;
public class SUT {
public String doSomething() throws IOException {
InputStreamReader reader =
new InputStreamReader(getFileAsStream(null, null));
BufferedReader bReader =
new BufferedReader(reader);
return bReader.readLine();
}
private InputStream getFileAsStream(Object resourceResolver, Object iconPath)
throws FileNotFoundException {
return new ByteArrayInputStream("".getBytes());
}
}
The following test code is an example of how to intercept the constructor calls:
package test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import static org.junit.Assert.assertEquals;
import static org.powermock.api.mockito.PowerMockito.doReturn;
import static org.powermock.api.mockito.PowerMockito.mock;
#RunWith(PowerMockRunner.class)
#PrepareForTest({ SUT.class })
public class SUTTest {
#Test
public void doSomethingReturnsValueFromBufferedReader() throws Exception {
// Arrange
SUT sut = new SUT();
InputStreamReader inputStreamReaderMock = mock(InputStreamReader.class);
BufferedReader bufferedReaderMock = mock(BufferedReader.class);
// Set your mocks up to be returned when the new ...Reader calls
// are executed in sut.doSomething()
PowerMockito.whenNew(InputStreamReader.class).
withAnyArguments().thenReturn(inputStreamReaderMock);
PowerMockito.whenNew(BufferedReader.class).
withArguments(inputStreamReaderMock).
thenReturn(bufferedReaderMock);
// Set the value you want bReader.readLine() to return
// when sut.doSomething() executes
final String bufferedReaderReturnValue = "myValue";
doReturn(bufferedReaderReturnValue).when(bufferedReaderMock).readLine();
// Act
String result = sut.doSomething();
// Assert
assertEquals(bufferedReaderReturnValue, result);
}
}
This hopefully helps you in your immediate problem. However, it seems to me that what you're creating will be a very slow, confusing and brittle test. Right now, you're mocking so much that it makes very hard to determine what you're actually trying to test.
The high amount of mocking probably indicates that the design of the code you're testing would need some work to improve testability. If you can't touch the code, then you can't - but try to make your test more readable and intuitive ("When this method is invoked, this thing should happen, because...").
to make this line work:
while ((iconEntry = bReader.readLine()) != null)
you must determine how many lines you want to read and add this to your test code:
when(bReader.readLine()).thenReturn("line number one").thenReturn("line number two");

Categories

Resources