I have the following method to which I want to test using JUnuit and Mockito.
public Map<String, String> getUserACLDetails(final int userId, final int networkId, final List<String> privilegeNames)
{
final Map<String, String> privilegeNameValue = new HashMap<>();
final Object aclDataString = cbClient.get(String.valueOf(userId));
Map<String, String> aclData = null;
if (null != aclDataString && !aclDataString.equals(NULL))
{
aclData = gson.fromJson(aclDataString.toString(), new HashMap<String, String>().getClass());
}
for (String privilegeName : privilegeNames)
{
String innerMapKey = String.valueOf(networkId) + UNDER_SCORE + privilegeName;
if (aclData.containsKey(innerMapKey))
{
privilegeNameValue.put(privilegeName, aclData.get(innerMapKey));
}
}
return privilegeNameValue;
}
Following is the testcase -
public void getUserACLDetailsWithReturnValueTest()
{
final int userId = 123;
final int networkId = 525;
List<String> privilegeNames = new ArrayList<>();
String privilegeName = "PRIVILEGE_ACCESS_VIEW";
String privilegeValue = "true";
privilegeNames.add(privilegeName);
Map<String, String> privilegeNameValues = new HashMap<>();
privilegeNameValues.put(privilegeName,privilegeValue);
Map<String, String> aclData = new HashMap<>();
aclData.put(String.valueOf(networkId) + "_" + privilegeName, privilegeValue);
privilegeName = "PRIVILEGE_ACCESS_EDIT";
privilegeValue = "false";
aclData.put(String.valueOf(networkId) + "_" + privilegeName, privilegeValue);
Mockito.when(couchbaseClient.get(String.valueOf(userId))).thenReturn(aclData);
assertEquals(privilegeNameValues, userAclDao.getUserACLDetails(userId, networkId, privilegeNames));
}
But when I execute the testcase I get the following error -
java.lang.AssertionError: expected: java.util.HashMap<{PRIVILEGE_CREATIVE_ACCESS_VIEW=true}> but was: java.util.HashMap<{PRIVILEGE_CREATIVE_ACCESS_VIEW=true}>
at org.junit.Assert.fail(Assert.java:93)
at org.junit.Assert.failNotEquals(Assert.java:647)
at org.junit.Assert.assertEquals(Assert.java:128)
at org.junit.Assert.assertEquals(Assert.java:147)
at com.zedo.nirvana.hriday.authorization.UserAclDaoCouchbaseImplTest.getUserACLDetailsWithReturnValueTest(UserAclDaoCouchbaseImplTest.java:153)
I am not able to understand what is going wrong here. Can anyone help.
Following is the correct testcase -
public void getUserACLDetailsWithReturnValueTest() {
final int userId = 123;
final int networkId = 525;
List<String> privilegeNames = new ArrayList<>();
String privilegeName = "PRIVILEGE_CREATIVE_ACCESS_VIEW";
String privilegeValue = "true";
privilegeNames.add(privilegeName);
final Object aclDataString = "{\"525" + "_" + privilegeName + "\": \"" + privilegeValue + "\"}";
Map<String, String> privilegeNameValues = new HashMap<>();
privilegeNameValues.put(privilegeName, privilegeValue);
Mockito.when(couchbaseClient.get(String.valueOf(userId))).thenReturn(aclDataString);
assertEquals(privilegeNameValues, userAclDao.getUserACLDetails(userId, networkId, privilegeNames));
}
I had made a mistake while returning the value when the mocked objects method was called.
Related
How to perform testing for it, Trying but bot getting
for reference adding code,
please help....
In Controller
#GET
#Path("/vitals/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response getVitalsById(#PathParam(value = "id")long id) {
Response response;
response = Response.ok().entity(iAppointmentService.getVitals(id)).build();
if(iAppointmentService.getVitals(id).isEmpty())
{
response = Response.ok().entity("Data Not Found For Entered Appointment Id").build();
}
return response;
}
In Repo
#Override
public List<Map<String, Object>> getVitals(long a_Id) {
List<Map<String, Object>> repos = null;
repos = jdbcTemplate.queryForList(vitals + a_Id + ";");
return repos;
}
For Testing in other package
#WebMvcTest
public class AppointmentServiceTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private IAppointmentService ias;
#Test
public void testGetVitals() throws Exception
{
UUID sid = UUID.fromString("79b804ed-765b-44ed-8e55-59b200aa536a");
List<Map<String, Object>> expected = new ArrayList<Map<String,Object>>();
Map<String, Object> safe_1 = new HashMap<String, Object>() ;
safe_1.put("vital_id",801);
safe_1.put("ecg",79);
safe_1.put("temperature",37.3);
safe_1.put("diabetes",159);
safe_1.put("prescription_rate",14);
safe_1.put("appointment_id",110);
expected.add(safe_1);
List<Map<String, Object>> actual = new ArrayList<>();
Map<String, Object> safe_2 = new HashMap<>();
safe_2.put("vital_id",801);
safe_2.put("ecg",79);
safe_2.put("temperature",37.3);
safe_2.put("diabetes",159);
safe_2.put("prescription_rate",14);
safe_2.put("appointment_id",110);
actual.add(safe_2);
//when(ias.getVitals(ArgumentMatchers.any())).thenReturn(actual);
mockMvc.perform(get("/appointments/vitals/102"))
.andExpect(status().isOk())
.andExpect(jsonPath("$[0].vital_id", is(801)))
.andExpect(jsonPath("$[1].ecg", is(79)))
.andExpect(jsonPath("$[2].temperature", is(37.3)))
.andExpect(jsonPath("$[3].diabetes", is(159)))
.andExpect(jsonPath("$[4].prescription_rate", is(14)))
.andExpect(jsonPath("$[5].appointment_id", is(110)));
}
}
i have 0 idea what to do in this testing class please help...
I am converting the below JsonObject to a String and keeping the string values in Hashmap. When I executed the application, I am getting an error
JSONObject["global_collector"] is not a string
How to solve the error?
#Service
public class CreditRiskService
{
public static String original1 = "";
public static String str;
public void getMatchingOpco() throws ParseException, FileNotFoundException, IOException
//public Map<String, String> getMatchingOpco() throws ParseException
{
File file1 = new File(getClass().getClassLoader().getResource("CredirRisk_corainputtoIIB.json").getFile());
JSONTokener jsonDataFile1 = new JSONTokener(new FileInputStream(file1));
JSONObject jsonObject1 = new JSONObject(jsonDataFile1);
//jsonObject1.optString(original1, original1)
File file2 = new File(getClass().getClassLoader().getResource("opco.json").getFile());
JSONTokener jsonDataFile2 = new JSONTokener(new FileInputStream(file2));
JSONObject jsonObject2 = new JSONObject(jsonDataFile2);
if(!JSONObject.NULL.equals(jsonObject1))
{
String jsonObjToString1 = (String)jsonObject1.toString();
original1=jsonObjToString1;
HashMap<String, String> map1 = new HashMap<>();
Iterator<String> itr1 = jsonObject1.keys();
while(itr1.hasNext())
{
String key = itr1.next();
String value = jsonObject1.getString(key);
System.out.println("Setting map key and value pairs");
map1.put(key,value);
System.out.println(key + ":" + value);
}
}
}
}
Following is the Json:
{
"target": "SUS",
"source": "CORA",
"request_tracker_id": "201013051429",
"request_datetimestamp": "2020-10-13 05:14:29",
"risk_code": null,
"payment_terms": null,
"op_code": "056",
"global_collector": null,
"credit_analyst": "CRDAB000",
"account_key": "USBL056155266B"
}
#RequestMapping(value = "/check", method = RequestMethod.GET)
public ResponseEntity<Product> createProducts() throws JsonProcessingException {
String reqUrl = "http://localhost:8080/home";
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
headers.setContentType(MediaType.APPLICATION_JSON);
Map<String, String> bodyParamMap = new HashMap<String, String>();
bodyParamMap.put("grant_type", "K1");
bodyParamMap.put("client_id", "K2");
bodyParamMap.put("client_secret", "sjxjkdcnjkk");
String reqBodyData = new ObjectMapper().writeValueAsString(bodyParamMap);
HttpEntity<String> requestEnty = new HttpEntity<>(reqBodyData, headers);
ResponseEntity<Product> result = restTemplate.postForEntity(reqUrl, requestEnty, Product.class);
return result;
}
I am geeting a JSON response form result which have access_token which I want to get.
I tried using JSONObject but it is not working. How Can I fetch the value of access_token
JSONObject jsonObject = JSONObject.fromObject(result.toString());
String m = jsonObject.get("access_token").toString();
I tried using this but it is showing compile time error
My output is accepted as
{"access_token":"ghdjhdjhhh","expires_in":2300}
I want to fetch this access_token
when you use postForEntity your Product.class is suppose to represent your result (responseType), so if your converters are well defined(normally the spring boot default ones are sufficient for json) with your class Product looking like this
public class Product {
#JsonProperty("access_token")
private String accessToken;
#JsonProperty("expires_in")
private Long expiresIn;
public String getAccessToken() {
return accessToken;
}
public Long getExpiresIn() {
return expiresIn;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public void setExpiresIn(Long expiresIn) {
this.expiresIn = expiresIn;
}
}
then you can get your result like this
ResponseEntity<Product> result = restTemplate.postForEntity(reqUrl, requestEnty, Product.class);
Product product = result.getBody();
String token = product.getAccessToken()
I have the following JSON file:
https://www.mediamarkt.de/de/product/productlistajax.json?categoryId=563612&sort=topseller&lazyLoading=true
EDIT: In case the above link does not work: https://pastebin.com/cTxp1RZ6
Now the only possibility I have found so far to fetch this JSON is using a Map:
Call<Map<String, Object>> call = liveApi.loadProductList(request.categoryId, request.sort, request.lazyLoading)
call.enqueue(new Callback<Map<String, Object>>() {
#Override
public void onResponse(Call<Map<String, Object>> call, Response<Map<String, Object>> response) {
Call<Map<String, Object> map = response.body();
}
});
But then I need to find all objects within the lower layers by keys. I would love to map those objects to my model classes with #SerializedName(), How could I do that?
All you have to do is creating custom mappings. Since your JSON document is pretty complex, you can try automatic mapping generators, but if they fail for any reason (dynamic properties, polymorphic values, improper camelCaseNaming detection, etc), you can always create your custom mappings:
final class Response {
#SerializedName("categories") final List<Category> categories = null;
#SerializedName("facettes") final List<Facet> facettes = null;
#SerializedName("productlistentries") final List<Map<String, Product>> productListEntries = null;
#SerializedName("last") final boolean isLast = Boolean.valueOf(false);
}
final class Category {
#SerializedName("amount") final int amount = Integer.valueOf(0);
}
final class Facet {
// ???
}
final class Product {
#SerializedName("name") final String name = null;
#SerializedName("modelNumber") final int modelNumber = Integer.valueOf(0);
#SerializedName("brandLogo") final String brandLogo = null;
#SerializedName("detailLink") final String detailLink = null;
#SerializedName("online") final boolean isOnline = Boolean.valueOf(false);
#SerializedName("imageURL") final String imageUrl = null;
#SerializedName("addToBasketUrl") final String addToBasketUrl = null;
#SerializedName("rating") final int rating = Integer.valueOf(0);
#SerializedName("ratingCount") final int ratingCount = Integer.valueOf(0);
#SerializedName("features") final List<Feature> features = null;
#SerializedName("price") final String price = null;
#SerializedName("vatLabel") final String vatLabel = null;
#SerializedName("fees") final List<Fee> fees = null;
#SerializedName("gtm") final Gtm gtm = null;
#SerializedName("productComparison") final ProductComparison productComparison = null;
#SerializedName("productWishlist") final ProductWishlist productWishlist = null;
#SerializedName("clubProduct") final boolean isClubProduct = Boolean.valueOf(false);
#SerializedName("onlineOnlyProduct") final boolean isOnlineOnlyProduct = Boolean.valueOf(false);
}
final class Feature {
#SerializedName("key") final String key = null;
#SerializedName("value") final String value = null;
}
final class Fee {
#SerializedName("value") final String value = null;
#SerializedName("dataLayer") final String dataLayer = null;
}
final class Gtm {
#SerializedName("name") final String name = null;
#SerializedName("id") final String id = null;
#SerializedName("price") final String price = null;
#SerializedName("brand") final String brand = null;
#SerializedName("category") final String category = null;
#SerializedName("dimension9") final String dimension9 = null;
#SerializedName("dimension10") final String dimension10 = null;
}
final class ProductComparison {
#SerializedName("dataLayer") final String dataLayer = null;
#SerializedName("dataUrl") final String dataUrl = null;
#SerializedName("text") final String text = null;
#SerializedName("additionalClasses") final String additionalClasses = null;
}
final class ProductWishlist {
#SerializedName("requestUrl") final String requestUrl = null;
#SerializedName("text") final String text = null;
}
It took about 15 minutes to write the mappings by hand, so they might have mistakes or typos. Note that I'm assuming your response is read-only and not supposed to be created manually to be sent elsewhere, so all of fields are declared final. One remark regarding the primitive fields: if you use 0 or false, then Java compiler can inline known-at-compile-time constants, so Type.value(...) is a sort of cheating to let javac think it's a runtime value that cannot be inlined. (You might want to generate getters, but IMHO fields for simple databags are easier to use and add less noise).
All you have to do is changing Call<Map<String, Object>> to Call<Response>.
Example in vanilla Java, not Retrofit:
try ( final Reader reader = getPackageResourceReader(Q43535942.class, "response.json") ) {
final Response response = gson.fromJson(reader, Response.class);
System.out.println(response.productListEntries.get(1).get("3486143").imageUrl);
}
Output:
//picscdn.redblue.de/doi/pixelboxx-mss-70874441/mobile_220_310_png/CRUNCH-GTO-4125-Verst%C3%A4rker-%28Class-D%29
I am using the below code to receive Tweets from Twitter4j Search API in the form of JSON response. I am receiving the result in the form of List as specified in Twitter4j search API in the line
List<Status> tweets = result.getTweets();
The problem is that the tweets returned as List where one Status entry is having non-empty and non-null GeoLocation whereas another Status entry is having a null or empty GeoLocation. Since to retrieve the relevant fields from each Status entry (i.e. Tweet), I iterate over the List and call getters which is throwing me null for the Status entries where the GeoLocation field is null.
The approach I tried to follow:
I created a POJO TweetJSON_2 (defined at the bottom of the post) with the relevant fields and their getters and setters. I am using Jackson ObjectMapper to handle null values like below:
JsonGenerator generator = new JsonFactory().createGenerator(os);
generator.setPrettyPrinter(new DefaultPrettyPrinter());
TweetJSON_2 rawJSON;
ObjectMapper mapper = new ObjectMapper();
//mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
mapper.setSerializationInclusion(Include.NON_NULL);
// ... rawJSON is populated ...
mapper.writeValue(generator, rawJSON);
However, when I am trying to get the geoLocation field from Status, using the below line which is marked with **
List<Status> tweets = result.getTweets();
I am getting the Java NullPointerException as follows:
[Mon Apr 20 11:32:47 IST 2015]{"statuses":[{"retweeted_status":{"contributors":null,"text":"<my text>",**"geo":null**,"retweeted":false,"in_reply_to_screen_name":null,"truncated":false,"lang":"en","entities":{"symbols":[],"urls":[],"hashtags": ... &include_entities=1","since_id_str":"0","completed_in":0.029}}
**Exception in thread "main" java.lang.NullPointerException
at analytics.search.twitter.SearchFieldsTweetsJSON_2.main(SearchFieldsTweetsJSON_2.java:78)**
For example: If I input a json String as
String s = "{\"first\": 123, \"second\": [{\"second_first\":null, \"second_second\":null}, {\"second_third\":null}, null], \"third\": 789, \"fourth\":null}";
The output should be like
"{\"first\": 123, \"third\": 789}";
What I want, is to replace all null elements from JSONArrays and all null key-value pairs from JSONObjects no matter at whatever level they are nested in my JSON response.
Object vs Tree Model Approach
I tried the Object Model parsing mechanism which is a javax.json.stream.JsonParser.Event based method but would need multiple times of access and object replacement on the JSON String depending on at what level the null is nested making this approach very complicated. At the same time if I use Tree Model mechanism, the entire JSON response would have to be stored as a Tree which may overflow my JVM heap memory because the JSON size can be pretty large based on my query parameters. I need to find a workable solution to overcome this problem. Any suggestions on solving the above discussed problem will be highly appreciated.
The code is as follows:
public class SearchFieldsTweetsJSON_2 {
/* Searches specific fields from Tweets in JSON format */
public static void main(String[] args) throws FileNotFoundException, IOException {
if (args.length < 2) {
System.out.println("java twitter4j.examples.search.SearchTweets [query][outputJSONFile]");
System.exit(-1);
}
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey("XXXXXXXXXXXXXXXXXXXXXXXXXX")
.setOAuthConsumerSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
.setOAuthAccessToken("NNNNNNNNN-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
.setOAuthAccessTokenSecret("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
.setJSONStoreEnabled(true);
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
try {
Query query = new Query(args[0]);
QueryResult result;
File jsonFile = new File(args[1]);
System.out.println("File Path : " + jsonFile.getAbsolutePath());
OutputStreamWriter os = new OutputStreamWriter(new FileOutputStream(jsonFile));
JsonGenerator generator = new JsonFactory().createGenerator(os);
generator.setPrettyPrinter(new DefaultPrettyPrinter());
TweetJSON_2 rawJSON;
ObjectMapper mapper = new ObjectMapper();
//mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
mapper.setSerializationInclusion(Include.NON_NULL);
do {
result = twitter.search(query);
List<Status> tweets = result.getTweets();
for (Status tweet : tweets) {
rawJSON = new TweetJSON_2();
rawJSON.setStatusId(Long.toString(tweet.getId()));
rawJSON.setUserId(Long.toString(tweet.getUser().getId()));
rawJSON.setUserName(tweet.getUser().getScreenName());
rawJSON.setStatusText(tweet.getText());
rawJSON.setGeoLocation(tweet.getGeoLocation().toString()); **<< Giving error at tweet.getGeoLocation() since GeoLocation is null**
mapper.writeValue(generator, rawJSON);
System.out.println(rawJSON.toString());
}
} while ((query = result.nextQuery()) != null);
generator.close();
System.out.println(os.toString());
} catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to search tweets : " + te.getMessage());
System.exit(-1);
}
}
}
I have defined my TweetJSON_2 Java object as follows:
public class TweetJSON_2 {
public String statusId;
public String statusText;
public String userId;
public String userName;
public String geoLocation;
public String getStatusId() {
return statusId;
}
public void setStatusId(String statusId) {
this.statusId = statusId;
}
public String getStatusText() {
return statusText;
}
public void setStatusText(String statusText) {
this.statusText = statusText;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getGeoLocation() {
return geoLocation;
}
public void setGeoLocation(String geoLocation) {
this.geoLocation = geoLocation;
}
#Override
public String toString() {
return "TweetJSON_2 [ statusId = " + statusId + ", statusText = " + statusText + "]";
}
}
I have tried with reconfiguring my POJO in the below way and it successfully replaced all the nulls as specified in the setter methods. Didn't need to follow either Tree or Event-based model parsing of JSON string. HTH
The modified TweetJSON_2 POJO:
public class TweetJSON_2 {
public Long statusId = null;
public String statusText = null;
public Long userId = null;
public String userName = null;
public GeoLocation geoLocation = null;
public Long getStatusId() {
if (this.statusId==null)
return new Long(0L);
return statusId;
}
public void setStatusId(Long statusId) {
if (statusId==null)
this.statusId = new Long(0L);
else
this.statusId = statusId;
}
public String getStatusText() {
if (this.statusText==null)
return new String("");
return statusText;
}
public void setStatusText(String statusText) {
if (statusText==null)
this.statusText = new String("");
else
this.statusText = statusText;
}
public Long getUserId() {
if (this.userId==null)
return new Long(0L);
return userId;
}
public void setUserId(Long userId) {
if (userId==null)
this.userId = new Long(0L);
else
this.userId = userId;
}
public String getUserName() {
if (this.userName==null)
return new String("");
return userName;
}
public void setUserName(String userName) {
if (userName==null)
this.userName = new String("");
else
this.userName = userName;
}
public GeoLocation getGeoLocation() {
if (this.geoLocation==null)
return new GeoLocation(0.0,0.0);
return geoLocation;
}
public void setGeoLocation(GeoLocation geoLocation) {
if (geoLocation==null)
this.geoLocation = new GeoLocation(0.0,0.0);
else
this.geoLocation = geoLocation;
}
#Override
public String toString() {
return "TweetJSON_2 [ statusId = " + statusId + ", statusText = " + statusText + "]";
}
}