I am using the following function in a groovy script:
private static List<List<String>> getCheckerFrameworkErrors(final String profile) {
// ----- Non relevant section starts
final List<String> checkerFrameworkLines = new ArrayList<>()
final String command = "mvn -e --no-transfer-progress clean compile -P${profile}"
final ProcessBuilder processBuilder = new ProcessBuilder(getOsSpecificCmd(command).split(' '))
processBuilder.redirectErrorStream(true)
final Process process = processBuilder.start()
// ----- Non relevant section ends
// ----- Relevant section starts
final BufferedReader reader = new BufferedReader(new InputStreamReader(process.inputStream))
String lineFromReader = reader.readLine()
while (lineFromReader != null) {
println(lineFromReader)
checkerFrameworkLines.add(lineFromReader)
lineFromReader = reader.readLine()
}
process.waitFor()
reader.close()
// ----- Relevant section ends
}
This method does not explicitly throw an exception and the signature of readLine() function is:
public String readLine() throws IOException
The signature of waitFor() is:
public abstract int waitFor() throws InterruptedException
which throws InterruptedException which is also another checked exception, still not error is thrown by the compiler.
groovy version is 4.0.3
According to my current knowledge, IOException is a checked exception and must be handled by a try-catch block or by explicitly adding throws to the method, but this script executes successfully without any error, what is the reason behind this?
Finally, after some research, found the answer to the question:
From Groovy docs:
Groovy automatically allows you to treat checked exceptions like unchecked exceptions. This means that you don’t need to declare any checked exceptions that a method may throw
Source: https://docs.groovy-lang.org/latest/html/documentation/#_exception_declaration
Related
I am performing instrumentation testing, in that I am invoking one of the activities which call 2 APIs when activity is created.
Now I want to write instrumentation test cases for this activity, where I have to mock the API response with mockWebServer of mockito. My mocking code works fine when I call one single API, but it fails when two APIs are getting called simultaneously.
Even there is another scenario let's say, we have API to fetch recent message data, but before that, we always authenticate the user by sending refresh token.
In such cases, we need to call API which authenticates the user and then another API to fetch message data. Hence we need to call 2 APIs one after another, let's say in a single method. How will I mock authentication API response and messages API response while writing test cases of that single method?
How should I deal with this issue? Is there any other approach to deal with such a situation where we need to call more than one API at the same time?
Also, I have used SystemClock.sleep(4000); as my callbacks were getting performed asynchronously.
Below is my code to mock API:
public class MyAPIActivityTest {
#Rule
public InstantTaskExecutorRule mInstantTaskExecutorRule = new InstantTaskExecutorRule();
#Rule
public ActivityTestRule<MyAPIActivity> myAPIActivityTestRule = new ActivityTestRule<>(MyAPIActivity.class, true, false);
MockWebServer mockWebServer;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void checkVisibilityOfTaskListMockedValidData() throws Exception {
myAPIActivityTestRule.launchActivity(null);
String fileName = "json_files/valid_api_response.json";
mockWebServer = new MockWebServer();
int PORT_NUMBER = 50205;
mockWebServer.start(PORT_NUMBER);
ApiUrls.BASE_QUERY_URL = mockWebServer.url("/").toString();
mockWebServer.enqueue(new MockResponse()
.setBody(getStringFromFile(getContext(), fileName)));
SystemClock.sleep(4000);
Assert.assertEquals(View.VISIBLE, myAPIActivityTestRule.IvDataIsPresent.getVisibility());
Assert.assertEquals(View.GONE, myAPIActivityTestRule.IvDataNotPresent.getVisibility());
}
#After
public void tearDown() throws Exception {
mockWebServer.shutdown();
}
public static String convertStreamToString(InputStream inputStream) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line).append(StringCharacters.NEW_LINE);
}
reader.close();
return stringBuilder.toString();
}
public static String getStringFromFile(Context context, String filePath) throws Exception {
final InputStream stream = context.getResources().getAssets().open(filePath);
String text = convertStreamToString(stream);
stream.close();
return text;
}
}
Any help is appreciated. Thanks in advance.
I am trying to have an integration test that throwns an exception for a void method to simulate a downed service. The method has a string param and a multipart file as a param and it does not seem to be working even though an exception is thrown for a void method with two string parameters.
Working integration test:
#Test
#DisplayName("500 response -- downed case mgmt microservice")
public void downedCaseMgmt() throws Exception {
BDDMockito.doThrow(new RuntimeException("mocking an error")).when(reportEventService).reportDocUpload(ArgumentMatchers.any(String.class), ArgumentMatchers.anyString());
//Rest assured portion
given().
multiPart("file", xlsxGoodFile).
params(paramsMap).
when().
post("").
then().
statusCode(500);
}
Non-working integration test:
#Test
#DisplayName("500 response -- downed object storage")
public void downedObjectStorage() throws Exception {
BDDMockito.doThrow(new RuntimeException("mocking an error")).when(objectStorageService).saveFileToObjectStorage(ArgumentMatchers.anyString(), ArgumentMatchers.any(File.class));
//Rest assured portion
given().
multiPart("file", xlsxGoodFile).
params(paramsMap).
when().
post("").
then().
statusCode(500);
}
Turns out that the function saveFileToObjectStorage had a null value because of the mockbean on objectStorageService and the fact that I was mocking a return. Error on my part and I resolved it with the following code:
#Test
#DisplayName("500 response -- downed db")
public void downedDb() throws Exception {
BDDMockito.doThrow(new RuntimeException("mocking an error")).when(excelDataRepository).
save(ArgumentMatchers.any());
//Rest assured portion
given().
multiPart("file", xlsxGoodFile).
params(paramsMap).
when().
post("").
then().
statusCode(500);
}
NOTE: the any() of ArgumentMatchers
There are many ways to create threads, The most simplest way I know to create a thread is the following:
new Thread(new Runnable(){
public void run(){
//thread work here
}
});
I am looking for the shorthand version for creating a message being sent to a Thread Handler-class;
Bundle bundle = new Bundle();
bundle.putString("KEY", "DONE");
Message msg = (new Message());
msg.setData(bundle);
msg.obtain(handler.obtainMessage());
handler.sendMessage(msg);
I think the Shorthand would be something like the following:
new Message().setData(new Bundle().putString("KEY","DONE")).obtain(handler.obtainMessage());
but for '.setData' I get the error;
The method setData(Bundle) in the type Message is not applicable for
the arguments (void)
What are my options experts?
NOTE: This implementation is for Android OS.
I want to get the specific error message of ANTLR4's parser.
And I found that there are two way to handle error: errorListener and errorHandler.
// set error handler
parser.removeErrorListeners();
parser.addErrorListener(new QueryErrorListener());
parser.setErrorHandler(new BailErrorStrategy());
But I'm confused about the difference between them.
I found that, errorListener can get the specific error message, but it can only print it or log it, can't throw a exception.
The implemention of errorListener as bellow:
public class QueryErrorListener extends BaseErrorListener {
private static final Logger LOGGER = LoggerFactory.getLogger(QueryDispatcher.class);
#Override
public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol,
int line, int charPositionInLine, String msg,
RecognitionException e)
{
List<String> stack = ((Parser)recognizer).getRuleInvocationStack(); Collections.reverse(stack);
String errorMessage = "line "+line+":"+charPositionInLine+" at "+
offendingSymbol+": "+msg;
LOGGER.error("rule stack: "+stack);
LOGGER.error(errorMessage);
QueryParseErrorStrategy queryParseErrorStrategy = new QueryParseErrorStrategy();
}
}
At the same time, the errorHandler can only throw a exception ParseCancellationException without any specific message.
public class BailErrorStrategy extends DefaultErrorStrategy {
/** Instead of recovering from exception {#code e}, re-throw it wrapped
* in a {#link ParseCancellationException} so it is not caught by the
* rule function catches. Use {#link Exception#getCause()} to get the
* original {#link RecognitionException}.
*/
#Override
public void recover(Parser recognizer, RecognitionException e) {
for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) {
context.exception = e;
}
throw new ParseCancellationException(e);
}
/** Make sure we don't attempt to recover inline; if the parser
* successfully recovers, it won't throw an exception.
*/
#Override
public Token recoverInline(Parser recognizer)
throws RecognitionException
{
InputMismatchException e = new InputMismatchException(recognizer);
for (ParserRuleContext context = recognizer.getContext(); context != null; context = context.getParent()) {
context.exception = e;
}
throw new ParseCancellationException(e);
}
/** Make sure we don't attempt to recover from problems in subrules. */
#Override
public void sync(Parser recognizer) { }
}
I've try to find a solution, add a transfer method to get detail message from ParseCancellationException, as bellow.
I found that I can get some message from a Token object of RecognitionException, but I can only find the line/charPositionInLine/offendingSymbol message, I don't know where is the detail message, like "missing 'xxx', expect 'yyy'"
public class ANTLRExceptionTransfer {
public static SemanticException transfer(RecognitionException re) {
String errorMsg = "";
Recognizer<?, ?> recognizer = re.getRecognizer();
Token offendingSymbol = re.getOffendingToken();
int line = offendingSymbol.getLine();
int charPositionInLine = offendingSymbol.getCharPositionInLine();
// ????????
String msg = "";
List<String> stack = ((Parser)recognizer).getRuleInvocationStack();
Collections.reverse(stack);
String errorMessage = "rule stack: "+stack;
errorMessage = "\nline "+line+":"+charPositionInLine+" at "+
offendingSymbol+": "+msg;
return new SemanticException(errorMessage);
}
}
Is it the right way to use errorHandler?
How can I get a exception with specific error message?
I find the setErrorHandler name a bit confusing. It should be consistent with what you can set there. It's for setting an error strategy (which is of course also some kind of handling...).
Both error listener and error strategy are means for the application to deal with parse errors. The error listener gets called for each encountered error and allows the application to collect them (e.g. to show them in a GUI). You'll get a pre-generated error message or can create an own one from the passed in parameters.
The error strategy is a class that determines how to continue after an error was found. The default stategy is to try to sync to the input stream and continue with parsing. Sometimes however you want the parser to stop immediately and avoid lengthy operations after an error was found. This so-called bail-out strategy is another class in ANTLR4, usually used for SLL parsing. See one of my projects for how that's used.
The thrown ParseCancellationException in the bail-out error strategy is an exception without any additional info. It's not meant for error handling (in the sense of sending it to the application/user, you have the error handler for that), but instead to throw an exception that's not one of the usual parser exceptions, in order to bypass all error catching and find a way out of the ongoing parse run as quick as possible. You have to catch this exception in your own code or it will bubble up to the root context of your application (and might cause the application to quit, depending on the target language).
Question may sound novice. But here i am everytime i try writing iphone5 in my cucumber feature file it parameterises the 5. I dont want this to happen and want it to just treat iphone5 as a string.
The line in my feature file causing this is:
Then upload iPhone5 image "xxxx.png"
which then gets following step definition:
#And("^then upload iPhone(\\d+) image \"([^\"]*)\"$")
public void then_upload_iPhone_image(int arg1, String arg2) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
Just remove regex for the digit and remove the parameter from the method.
#Given("^I upload to iphone5$")
public void I_upload_to_iphone() throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
in your case
#And("^then upload iPhone5 image \"([^\"]*)\"$")
public void then_upload_iPhone_image(String arg2) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}