The code is as shown below. I want it go test all the elements of keyNames.
But, it stops if any test fails and doesn't iterate through all array elements.
My understanding being, in assertAll all assertions are executed, and any failures should be reported together.
Thanks for your time and help.
private void validateData(SearchHit searchResult, String [] line){
for(Integer key : keyNames){
String expectedValue = getExpectedValue(line, key);
String elementName = mappingProperties.getProperty(key.toString());
if (elementName != null && elementName.contains(HEADER)){
assertAll(
() -> assumingThat((expectedValue != null && expectedValue.length() > 0),
() -> {
String actualValue = testHelper.getHeaderData(searchResult, elementName);
if(expectedValue != null) {
assertEquals(expectedValue, actualValue, " ###Element Name -> " + elementName +" : Excepted Value ### " + expectedValue + " ### Actual Value ###" + actualValue);
}
}
)
);
}
}
}
The javadoc of Assertions.assertAll() states :
Asserts that all supplied executables do not throw exceptions.
And actually you provide a single Executable in assertAll() at each iteration.
So a failure in any iteration of the loop terminates the test execution.
In fact you invoke multiple times assertAll() by requesting at most a single assertion at each time :
if(expectedValue != null) {
assertEquals(expectedValue, actualValue, " ###Element Name -> " + elementName +" : Excepted Value ### " + expectedValue + " ### Actual Value ###" + actualValue);
}
What you want is doing the reverse : invoking assertAll() by passing multiple Executable instances performing the required assertions.
So you could collect them in a List with a classic loop and pass it in this way :
assertAll(list.stream()) or creating a Stream<Executable> without any collect and pass it directly such as assertAll(stream).
Here is a version with Stream (not tested at all) but you should get the idea :
Stream<Executable> executables =
keyNames.stream()
.map(key->
// create an executable for each value of the streamed list
()-> {
String expectedValue = getExpectedValue(line, key);
String elementName = mappingProperties.getProperty(key.toString());
if (elementName != null && elementName.contains(HEADER)){
assumingThat((expectedValue != null && expectedValue.length() > 0),
() -> {
String actualValue = testHelper.getHeaderData(searchResult, elementName);
if(expectedValue != null) {
assertEquals(expectedValue, actualValue, " ###Element Name -> " + elementName +" : Excepted Value ### " + expectedValue + " ### Actual Value ###" + actualValue);
}
}
);
}
}
);
Assertions.assertAll(executables);
assertAll() groups all assertions and errors that were passed to that invocation of assertAll(). It won't group assertions across all invocations that occur during the test method.
In the code you posted, you pass a single assertion lambda into assertAll(). It won't group errors across the multiple keys, as each key has a separate invocation of assertAll().
To ensure you separately test all values in a collection, take a look at parameterized tests.
As indicated by #user31601, parameterized tests (see documentation) automatically test all cases independently.
This leads to the following (somewhat simpler) code):
#ParameterizedTest
#MethodSource("getKeys")
void testKey(String key) {
String elementName = mappingProperties.getProperty(key.toString());
assumeTrue(elementName != null);
assumeTrue(elementName.contains(HEADER));
String expectedValue = getExpectedValue(line, key);
assumeTrue(expectedValue != null);
assumeTrue(expectedValue.length() > 0);
String actualValue = testHelper.getHeaderData(searchResult, elementName);
String doc = String.format("name: %s, expected %s, actual %s", elementName, expectedValue, actualValue);
assertEquals(expectedValue, actualValue, doc);
}
private static Stream<String> getKeys() {
return keyNames.stream()
}
Related
Can’t convert String into json, and it seems that it will be superfluous for the entire string.
Was thinking maybe json might have helped me out here, but it doesn't seem to give me what I want or I don't know how it will be work.
How I can check the string?
I need to check:
METHOD: GET and URL: http://google.com/
also to check the BODY contains the fields userId, replId and view (no values, only keys)
I was trying to find a way to check that:
if (msg.contains("METHOD: GET") && msg.contains("URL: http://google.com/") && msg.contains("BODY: etc...")) {
System.out.println("ok");
}
It doesn't work. Some values from BODY that are dynamic and that's why for BODY the check won't pass if it’s so hardcoded String. And I guess there're any better ways to do that.
I'd like to have something like:
Assert.assertEquals(
msg,
the expected value for METHOD, which contains GET); // same here for URL: http://google.com/
Assert.assertEquals(
msg,
the expected value for BODY that has userId, replId, and view fields); // or make this assertion for each field separately, such as there is an assertion for the userId field, the same assertions for replId and view
And here's the String:
String msg = "METHOD: GET\n" +
"URL: http://google.com/\n" +
"token: 32Asdd1QQdsdsg$ff\n" +
"code: 200\n" +
"stand: test\n" +
"BODY: {\"userId\":\"11022:7\",\"bdaId\":\"110220\",\"replId\":\"fffDss0400rDF\",\"local\":\"not\",\"ttpm\":\"000\",\"view\":true}";
I can't think of any way to check that. Any ideas?
You can use the java.util.List Interface (of type String) and place the string contents into that list. Then you can use the List#contains() method, for example:
String msg = "METHOD: GET\n" +
"URL: http://google.com/\n" +
"token: 32Asdd1QQdsdsg$ff\n" +
"code: 200\n" +
"stand: test\n" +
"BODY: {\"userId\":\"11022:7\",\"bdaId\":\"110220\",\"replId\":\"fffDss0400rDF\",\"local\":\"not\",\"ttpm\":\"000\",\"view\":true}";
// Split contents of msg into list.
java.util.List<String> list = Arrays.asList(msg.split("\n"));
if (list.contains("METHOD: GET")) {
System.out.println("YUP! Got: --> 'METHOD: GET'");
}
else {
System.out.println("NOPE! Don't have: --> 'METHOD: GET'");
}
I've tried to use Assert:
String[] arr1 = msg.split("\n");
Map<String, String> allFieldsMessage = new HashMap<>();
for (String s : arr1) {
String key = s.trim().split(": ")[0];
String value = s.trim().split(": ")[1];
allFieldsMessage.put(key, value);
}
Assert.assertEquals(
allFieldsMessage.get("METHOD"),
"GET"
);
And the same for URL. But my problem is in BODY part. I thought maybe try to parse this particular part of String into json and then only check the necessary keys.
I'm trying to filter jsonPath by type. To extract Integers
I would expect this will return nothing as 'xx' is not integer:
JsonPath.read("{'status': 'xx'}", "$.status", Criteria.where(".status").is(Integer.class));
Similarly this
JsonPath.read("{'status': 'xx'}", "$.status", Criteria.where(".status").eq(200));
both cases returns String = "xx"
I would expect it to return either null or empty string as it doesn't match number 200.
Correct #i.bondarenko, I would simply add - for the first check of searching whether status value is an Integer - that he/she should use a Pattern to pass to the filter, like for example
Pattern numberPattern = Pattern.compile("\\d+");
Filter filter = filter(where("status").regex(numberPattern));
Object test = JsonPath.read("{\"status\": \"xx\"}", "$[?].status", filter);
System.out.println("Test : " + test);
That will print Test : []
UPDATED
It is a JSONArray indeed, therefore, you already have the Integers of your whole JSON in that array (if they exist). For example,
Pattern numberPattern = Pattern.compile("\\d+");
Filter filter = filter(where("status").regex(numberPattern));
net.minidev.json.JSONArray test = JsonPath.read("{\"status\": 300}", "$[?].status", filter);
if (!test.isEmpty()) {
for (Object object : test) {
System.out.println("Test : " + object.toString());
}
}
So, there is no need to add try-catch, it is enough to just check the size of your JSONArray result
You should use $[?].status as json path for criteria.
Also where("field").is("value") accept value but not a class.
You could have a look at implementation of Criteria.eq(...)
public Criteria eq(Object o) {
return is(o);
}
Here is the code:
public static void main(String[] args) {
Criteria criteria = Criteria.where("status").gt(10);
Object read = JsonPath.read("{'status': 18}", "$[?].status", criteria);
System.out.println("First: " + read);
read = JsonPath.read("{'status': 2}", "$[?].status", criteria);
System.out.println("Second: " + read);
criteria = Criteria.where("status").is("value");
read = JsonPath.read("{'status': 'value'}", "$[?].status", criteria);
System.out.println("Third: " + read);
criteria = Criteria.where("status").is("value");
read = JsonPath.read("{'status': 'NON'}", "$[?].status", criteria);
System.out.println("Third: " + read);
}
Output:
First: [18]
Second: []
Third: ["value"]
Third: []
I am threading a time consuming for-loop and executing them inside N number of threads. A continue statement is throwing error
Getting the error "Continue cannot be used outside of a loop"
for (final Message m : messagelistholder.getMessage()) {
Callable<Void> tasksToExecute = new Callable<Void>() {
public Void call() {
if (guidanceonly1 == true && !QuoteUtil.isECPQuote(list.get(0))) {
String msg = "Message From " + m.getSource() + " when retrieving Guidance values: "
+ m.getDescription();
String lcladdStatusMessages = CommonUtil.getLoclizedMsg(
"PRCE_LNE_ITM_MSG_FRM_WHN_RETRVNG_GUIDNCE_VAL",
new String[]{m.getSource(), m.getDescription()}, msg);
list.get(0).addStatusMessages("Info", lcladdStatusMessages);
} else if ("Error".equalsIgnoreCase(m.getSeverity())) {
if (m.getCode().indexOf("_NF") > 0) {
continue; // price not found due to private sku
}
if ("Eclipse".equalsIgnoreCase(m.getSource())) {
String msg1 = "Please check Sold To customer data. ";
String lcladdStatusMessages1 = CommonUtil
.getLoclizedMsg("PRCE_LNE_ITM_PLS_CHK_SLDTO_CUST_DTA", null, msg1);
String msg2 = "Discount information may not be returned from Optimus due to "
+ m.getSeverity() + " From " + m.getSource() + " " + m.getDescription();
String lcladdStatusMessages2 = CommonUtil.getLoclizedMsg(
"PRCE_LNE_ITM_DSCNT_INFO_MNT_RTRND_FRM_OPTMS_DUETO_FRM",
new String[]{m.getSeverity(), m.getSource(), m.getDescription()}, msg2);
list.get(0).addStatusMessages(m.getSeverity(),
(m.getDescription().contains("MDCP") ? lcladdStatusMessages1 : "")
+ lcladdStatusMessages2);
} else {
if (response1.getItems() == null) {
String lcladdStatusMessages = CommonUtil.getLoclizedMsg("PRCE_LNE_ITM_OPTMS_ERR",
new String[]{m.getSource(), m.getDescription()}, m.getDescription());
list.get(0).addStatusMessages("Error", lcladdStatusMessages);
list.get(0).setOptimusError(true);
} else {
if (!QuoteUtil.isECPQuote(list.get(0))) {
String lcladdStatusMessages = CommonUtil.getLoclizedMsg(
"PRCE_LNE_ITM_MSG_FRM_WHN_RETRVNG_GUIDNCE_VAL",
new String[]{m.getSource(), m.getDescription()},
"Message From " + m.getSource() + " " + m.getDescription());
list.get(0).addStatusMessages("Info", lcladdStatusMessages);
list.get(0).setOptimusError(true);
}
}
}
}
if (list.get(0).getFlags().get(QtFlagType.ESCALATIONFORPARTNER) != null) {
list.get(0).getFlags().get(QtFlagType.ESCALATIONFORPARTNER).setFlgVl(null);
}
if (m.getCode() != null) {
String pricingServiceMsgCode = m.getCode();
String pricingServiceSeverity = m.getSeverity();
Map<Integer, AutoEscalationScenario> categoryMap;
if (StringUtils.equals("ERROR", pricingServiceSeverity)) {
categoryMap = getScenario("SEVERITY", globalAccount1, null, true, null);
if (categoryMap.size() != 0) {
finalCategorylist.get(0).putAll(categoryMap);
}
}
if (partnerExclusivityAutoEscalation1) {
categoryMap = getScenario(pricingServiceMsgCode, globalAccount1, null, true, null);
if (categoryMap != null && categoryMap.size() != 0) {
finalCategorylist.get(0).putAll(categoryMap);
}
}
}
return null;
}
};
runnableTasks.add(tasksToExecute);
}
Can someone help me to skip the particular loop for the speicified condition but without using continue statement since it throws error.
What's happening is that you are actually calling continue outside of a loop because the call() function itself does not have a for loop, so it doesn't matter if are only calling call() from a loop.
What can you do to fix this is making the call function to return a boolean and replacing the continues with return true and return false if no return true has been reached.
Then replace the:
call()
on the loop(s) for
if(call()) continue
So the I'm not saying I fully understand you code, but it appears that you are using continue to break out of that thread. On a normal multi-threaded application, it looks like you are launching multiple threads from one one loop. The continue call is inside the new thread, not the loop. As soon as you start writing the call() method, you leave the loop to run it. Looking at the code, I would try replacing continue with return. Normally I would try running it myself before I suggest it, but without the rest of the code I cannot verify that it works.
I am currently translating legacy groovy class with methods to Java, and for most methods it has been easy with slight modifications.
Now I am stuck in a method that takes closure as param:
transformer.renameNumbers([:], { Number->
return "${number.name}#somecompany.com"
})
}
the renameNumbers implementation is :
renameNumbers(Map<String,String> renameMap, someclosure = {it}) {
numbers.each { it->
if(newUsername == null ) {
newNumbername = someclosure.call(it)
}
if(newNumbername!=null && newNumbername!=it.number) {
def oldNumber= it.number
it.number = newNumbername
log.info("Changed numbername key of from '$oldNumber' to '$newNumbername'")
}
}
The problem is that if i try to simply pass: transformer.renameNumbers(Map, Object)
it complains:
groovy.lang.MissingMethodException: No signature of method: org.eclipse.emf.ecore.util.EObjectContainmen.call() is applicable for argument types:
I guess it's because my normal Java Object doesn't have call() methods.
Is there a way to circumvent this? For example if I create custom Java class with custom call method ?
Thanks
You could try using Java 8s functional interfaces like Function<T,R> and Lambdas:
//Function<Number, String> f = (n) -> n.name + "#somecompany.com";
transformer.renameNumbers(new HashMap<>(), (n) -> n.name + "#somecompany.com");
Usage :
void renameNumbers(Map<String, String> renameMap, Function<Number, String> somefunction) {
numbers.forEach(it -> {
String newNumbername = somefunction.apply(it); // <-----
if (newNumbername != null && newNumbername != it.number) {
String oldNumber = it.number;
it.number = newNumbername;
log.info("Changed numbername key of from '" + oldNumber + "' to '" + newNumbername + "'");
}
});
}
I have a java code that generates a request number based on the data received from database, and then updates the database for newly generated
synchronized (this.getClass()) {
counter++;
System.out.println(counter);
System.out.println("start " + System.identityHashCode(this));
certRequest
.setRequestNbr(generateRequestNumber(certInsuranceRequestAddRq
.getAccountInfo().getAccountNumberId()));
System.out.println("outside funcvtion"+certRequest.getRequestNbr());
reqId = Utils.getUniqueId();
certRequest.setRequestId(reqId);
System.out.println(reqId);
ItemIdInfo itemIdInfo = new ItemIdInfo();
itemIdInfo.setInsurerId(certRequest.getRequestId());
certRequest.setItemIdInfo(itemIdInfo);
dao.insert(certRequest);
addAccountRel();
counter++;
System.out.println(counter);
System.out.println("end");
}
the output for System.out.println() statements is `
1
start 27907101
com.csc.exceed.certificate.domain.CertRequest#a042cb
inside function request number66
outside funcvtion66
AF88172D-C8B0-4DCD-9AC6-12296EF8728D
2
end
3
start 21695531
com.csc.exceed.certificate.domain.CertRequest#f98690
inside function request number66
outside funcvtion66
F3200106-6033-4AEC-8DC3-B23FCD3CA380
4
end
In my case I get a call from two threads for this code.
If you observe both the threads run independently. However the data for request number is same in both the cases.
is it possible that before the database updation for first thread completes the second thread starts execution.
`
the code for generateRequestNumber() is as follows:
public String generateRequestNumber(String accNumber) throws Exception {
String requestNumber = null;
if (accNumber != null) {
String SQL_QUERY = "select CERTREQUEST.requestNbr from CertRequest as CERTREQUEST, "
+ "CertActObjRel as certActObjRel where certActObjRel.certificateObjkeyId=CERTREQUEST.requestId "
+ " and certActObjRel.certObjTypeCd=:certObjTypeCd "
+ " and certActObjRel.certAccountId=:accNumber ";
String[] parameterNames = { "certObjTypeCd", "accNumber" };
Object[] parameterVaues = new Object[] {
Constants.REQUEST_RELATION_CODE, accNumber };
List<?> resultSet = dao.executeNamedQuery(SQL_QUERY,
parameterNames, parameterVaues);
// List<?> resultSet = dao.retrieveTableData(SQL_QUERY);
if (resultSet != null && resultSet.size() > 0) {
requestNumber = (String) resultSet.get(0);
}
int maxRequestNumber = -1;
if (requestNumber != null && requestNumber.length() > 0) {
maxRequestNumber = maxValue(resultSet.toArray());
requestNumber = Integer.toString(maxRequestNumber + 1);
} else {
requestNumber = Integer.toString(1);
}
System.out.println("inside function request number"+requestNumber);
return requestNumber;
}
return null;
}
Databases allow multiple simultaneous connections, so unless you write your code properly you can mess up the data.
Since you only seem to require a unique growing integer, you can easily generate one safely inside the database with for example a sequence (if supported by the database). Databases not supporting sequences usually provide some other way (such as auto increment columns in MySQL).