catch block not covered in unit testing - java

I have written a test case for the exception is passed but does not cover code coverage.
Please help me I tried many ways but doesn't resolve.
public String checkJiraStatus(HttpURLConnection httpURLConnection) throws IOException {
try {
BufferedReader in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
String inputLine;
StringBuilder stringBuilder = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
stringBuilder.append(inputLine);
}
in.close();
JSONObject jsonObject = new JSONObject(String.valueOf(stringBuilder));
JSONObject fields = (JSONObject) jsonObject.get("fields");
JSONObject status = (JSONObject) fields.get("status");
return (String) status.get("name");
}catch (IOException |JSONException ioException) {
throw new IOException("Problem while fetching the data"+ioException.getMessage());
}
}
test case passes correctly but didn't give code coverage.
#Test(expected = Exception.class)
public void testIoException() throws Exception {
when(mockJiraFunctions.checkJiraStatus(any())).thenThrow(new
IOException("Problem while fetching the data"));
jiraFunctions.checkJiraStatus(any());
}

As I mentioned in comment, you should run your real method to have a coverage.
And you should make a situation, where your function will throw an exception. For example in your case you can make a mock object of HttpURLConnection class and make him throw IOException when you call getInputStream() method on it.
So your test will be like
#Test(expected = Exception.class)
public void test() {
HttpURLConnection connectionMock = mock(HttpURLConnection.class);
when(connectionMock.getInputStream()).thenThrow(new IOException());
jiraFunctions.checkJiraStatus(connectionMock);
}

Related

Mocking BufferedReader and HttpsURLConnection to get the token

I am trying to open the HttpsURLConnection from URL which I have created the mock object. But it is throwing the AbstractMethodError when I mock the below method. Actually I have to write a Junit Test Case for the below method using Mockito.
I have Mocked the below objects and failed to Test Completely. I have given a piece of work which I have done with mockings.
public String createBearerToken(HttpServletRequest request) throws Exception{
BufferedReader bearerTokenReader = null;
String returnMessage = null;
HttpsURLConnection conn = null;
conn = MyClass.makeConnection();
StringBuilder response = new StringBuilder();
bearerTokenReader = new BufferedReader(new InputStreamReader(conn.getInputStream(), utf-8){
String responseLine = null;
while((responseLine = StringEscapeUtils.escapeHtml4(bearerTokenReader.readLine()) != null)
{
response.append(responseLine.trim());
}
returnMessage = response.toString();
}
I have created the Mock Test Method as the below:
#Test
public void testGetBearerTokenSuccess() throws Exception {
URL url = PowerMockito.mock(URL.class);
String urlStr = "https://localhost:8080/home";
PowerMockito.whenNew(URL.class).withArguments(anyString()).thenReturn(url);
HttpURLConnection httpUrlConnection = Mockito.mock(HttpURLConnection.class);
Mockito.when(url.openConnection().thenReturn(httpUrlConnection);
//getting the **java.lang.AbstractMethodError" at java.net.URL.openConnection** error in the above line while calling the ```url.openConnection```.
}
}
also the BufferedReader mocking part for the above code having some doubts to write the test cases for that. Need help to complete the above java method.

Spring Boot - Throwing IOException when mocking BufferedReader

I am currently trying to test a service in Spring Boot. It should read a file from a BufferedReader. The first test works just fine, but the one where I try to mock the IOException is not.
HTMLService:
#MockBean
HTMLService htmlService;
public String read(String fileName, String username) {
String s = null;
String filePath = new File("").getAbsolutePath();
String path = filePath+"/src/main/resources/html/"+fileName;
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
String line = br.readLine();
StringBuilder sb = new StringBuilder();
while (line != null) {
sb.append(line).append("\n");
line = br.readLine();
}
s = sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
s = s.replace("KINO-USERNAME", username);
return s;
}
Test:
#Test
void testReadException() {
when(htmlService.read("Registration.html", "DrBackmischung")).thenReturn("Test");
try {
BufferedReader br = Mockito.mock(BufferedReader.class);
when(br.readLine()).thenThrow(IOException.class);
} catch (IOException e) {
e.printStackTrace();
}
assertThrows(IOException.class, new Executable() {
#Override
public void execute() throws Throwable {
htmlService.read("Registration.html", "DrBackmischung");
}
});
}
I've tried mocking it different ways, but nothing seems to work. Is there a working approach?
It seems you are mocking BufferedReader, however the BufferedReader used inside your HTMLService class is new BufferedReader, so it is initializing a new instance of BufferedReader, and definitley not pointing towards your mock instance..
Why dont you just mock the return of the read method() to throw IOException instead.
when(htmlService.read("Registration.html", "DrBackmischung")).thenThrow(IOException.class);
Honesty I cant see the validity of such a test (Towards that a BufferedReader throws an IOException)..unless you have an important business logic (Another method/Service, that could be impacted), but testing an isolated IOException doesnt seem to provide any benefit.

Can't download html source from a web page

im having problems downloading html source from a web page in android. I run the http client in a different thread and it is able to get the html text ( i logged the result) but later when i try to work with the downloaded html text the variable seems to be empty from the main thread. I assume the problem is rising because im unable to synchronize threads but i don't know how to fix it for now. When i debug the code, the global variable contains data in the run function but when i join threads and look after the join method the variable is empty. Here is my code (class which i run in a different thread)
public class LutrijaHr {
public String url;
public String savedHtml;
public LutrijaHr(String s){
this.url = s;
savedHtml = "";
}
public String donwloadSource(String passedUrl) throws Exception{
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet(passedUrl);
HttpResponse response = client.execute(request);
String html = "";
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
str.append(line);
}
in.close();
html = str.toString();
savedHtml += html;
return html;
}
}
Parts of code from the main class:
String test = "";
LutrijaHr lhr = new LutrijaHr("https://www.lutrija.hr");
#Override
public void run() {
try {
test = lhr.donwloadSource(lhr.url);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lhr.savedHtml = test;
Log.d("test", test);
}
Here is the part where i try to join the threads but the variable is empty
if (v.getId() == R.id.checkNumber){
Thread t = new Thread(new LotoMain(), "Page thread");
t.start();
try {
t.join();
etCheckedNumber.setText(lhr.savedHtml);
String smrki = test;
Log.d("testdsadasd", lhr.savedHtml);
Log.d("BOZO BOZO" ,test) ;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.d("BOZO BOZO BOZO" ,test) ;
e.printStackTrace();
}
}
I would like to solve this problem without using the android asynctask class because i want to learn a bit about threads and how they operate.
Use "Lock"
Add this code to main class:
public Lock workingLock = new ReentrantLock();
String test = "";
LutrijaHr lhr = new LutrijaHr("https://www.lutrija.hr");
#Override
public void run() {
try {
workingLock.lock();
test = lhr.donwloadSource(lhr.url);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lhr.savedHtml = test;
workingLock.unlock;
Log.d("test", test);
}
Now use it in:
if (v.getId() == R.id.checkNumber){
Thread t = new Thread(new LotoMain(), "Page thread");
try {
try {
workingLock.lock();
} catch (Exception e) {
e.printStackTrace();
}
etCheckedNumber.setText(lhr.savedHtml);
String smrki = test;
Log.d("testdsadasd", lhr.savedHtml);
Log.d("BOZO BOZO" ,test) ;
workingLock.unlock();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
Log.d("BOZO BOZO BOZO" ,test) ;
e.printStackTrace();
}
}
Try this, it will return the source of a given page as one long string which you can then manipulate however you need, and as its a standalone class/method you can call it on the UI thread or asyc or however you choose to.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
public class WebPage {
public static String getWebSource(String Url) throws IOException {
URL url = new URL(Url);
URLConnection urlConnection = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(
urlConnection.getInputStream(), "UTF-8"));
String inputLine;
StringBuilder sb = new StringBuilder();
while ((inputLine = br.readLine()) != null)
sb.append(inputLine);
br.close();
return sb.toString();
}
}
Edit: If you want to call it from the UI thread, android won't by default let you do that. you will need to change the apps thread policy which can by done by running this when the app starts (Required a min API of 9)
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
I "solved" the problem with declaring
String test = "";
as
static String test = "";
Even if this soultion works i don't understand why it wouldn't work with my original solution. If someone could light up this for me it would be really helpfull

Deal with huge JSON responses

I think I need to rewrite some modules of my app because when the number of entities that are rendered increases, it fails and errors too. At this moment, I'm using Jackson and HttpClient. As much as I trust in Jackson, something tells me that the problem is the second lib. Can HttpClient deal with large responses? (e.g. this one that is about 400 lines)
Besides that, in my app, the way I parse the request goes something like this:
public Object handle(HttpResponse response, String rootName) {
try {
String json = EntityUtils.toString(response.getEntity());
// better "new BasicResponseHandler().handleResponse(response)" ????
int statusCode = response.getStatusLine().getStatusCode();
if ( statusCode >= 200 && statusCode < 300 ) {
return createObject(json, rootName);
}
else{
return null;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Object createObject (String json, String rootName) {
try {
this.root = this.mapper.readTree(json);
String className = Finder.findClassName(rootName);
Class clazz = this.getObjectClass(className);
return mapper.treeToValue(root.get(rootName), clazz);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
How I can improve this piece of code to be more efficient with large responses?
Thanks in advance!
There's no need to create the String json, as ObjectMapper#readTree can accept an InputStream as well. For example, this will be slightly more efficient:
public Object handle(HttpResponse response, String rootName) {
try {
int statusCode = response.getStatusLine().getStatusCode();
if ( statusCode >= 200 && statusCode < 300 ) {
return createObject(response.getEntity().getContent(), rootName);
}
else{
return null;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Object createObject (InputStream json, String rootName) {
try {
this.root = this.mapper.readTree(json);
String className = Finder.findClassName(rootName);
Class clazz = this.getObjectClass(className);
return mapper.treeToValue(root.get(rootName), clazz);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
Ive had 1000+ line json responses handled without issue, so that shouldnt be a problem. As for better ways of doing it, Google GSON is amazing, itll map your json to you java object with no special parsing code whatsoever.
I guess you could read data to a good old StringBuffer. Something like
HttpEntity httpEntity = httpResponse.getEntity();
if (httpEntity != null) {
InputStream is = AndroidHttpClient.getUngzippedContent(httpEntity);
br = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder(8192);
String s;
while ((s = br.readLine()) != null) sb.append(s);
}

Read utf-8 url to string java

Good day. Have just switched from objective-c to java and trying to read url contents normally to string. Read tons of posts and still it gives garbage.
public class TableMain {
/**
* #param args
*/
#SuppressWarnings("deprecation")
public static void main(String[] args) throws Exception {
URL url = null;
URLConnection urlConn = null;
try {
url = new URL("http://svo.aero/timetable/today/");
} catch (MalformedURLException err) {
err.printStackTrace();
}
try {
urlConn = url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader input = new BufferedReader(new InputStreamReader(
urlConn.getInputStream(), "UTF-8"));
StringBuilder strB = new StringBuilder();
String str;
while (null != (str = input.readLine())) {
strB.append(str).append("\r\n");
System.out.println(str);
}
input.close();
} catch (IOException err) {
err.printStackTrace();
}
}
}
What's wrong? I get something like this
??y??'??)j1???-?q?E?|V??,??< 9??d?Bw(?э?n?v?)i?x?????Z????q?MM3~??????G??љ??l?U3"Y?]????zxxDx????t^???5???j?‌​?k??u?q?j6?^t???????W??????????~?????????o6/?|?8??{???O????0?M>Z{srs??K???XV??4Z‌​??'??n/??^??4????w+?????e???????[?{/??,??WO???????????.?.?x???????^?rax??]?xb??‌​& ??8;?????}???h????H5????v?e?0?????-?????g?vN
Here is a method using HttpClient:
public HttpResponse getResponse(String url) throws IOException {
httpClient.getParams().setParameter("http.protocol.content-charset", "UTF-8");
return httpClient.execute(new HttpGet(url));
}
public String getSource(String url) throws IOException {
StringBuilder sb = new StringBuilder();
HttpResponse response = getResponse(url);
if (response.getEntity() == null) {
throw new IOException("Response entity not set");
}
BufferedReader contentReader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line = contentReader.readLine();
while ( line != null ){
sb.append(line)
.append(NEW_LINE);
line = contentReader.readLine();
}
return sb.toString();
}
Edit: I edited the response to ensure it uses utf-8.
This is a result of:
You are fetching data that is UTF-8 encoded
You are didn't specify, but I surmise you are printing it to the console on a Windows system
The data is being received and stored correctly, but when you print it the destination is incapable of rendering the Russian text. You will not be able to just "print" the text to stdout unless the ultimate display handler is capable of rendering the characters involved.

Categories