I have the following class which contains a hard coded URL that never changes:
public class HttpClient {
private final String DOWNLOAD_URL = "http://original.url.json";
public String readJsonDataFromUrl() throws IOException {
URLConnection urlConnection = getUrlConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer content = new StringBuffer();
String readLine = "";
while ((readLine = reader.readLine()) != null) {
content.append(readLine);
}
return content.toString();
}
private URLConnection getUrlConnection() throws IOException {
URL jsonLocator = new URL(DOWNLOAD_URL);
return jsonLocator.openConnection();
}
}
Now imagine that I'd like to expect the IOException in my test. In my opinion, the only way to do that is to rewrite the complete class in a mock object because of the final variable:
public class HttpClientMock extends HttpClient {
private final String DOWNLOAD_URL = "http://wrong.test.url.json";
#Override
public String readJsonDataFromUrl() throws IOException {
URLConnection urlConnection = getUrlConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer content = new StringBuffer();
String readLine = "";
while ((readLine = reader.readLine()) != null) {
content.append(readLine);
}
return content.toString();
}
private URLConnection getUrlConnection() throws IOException {
URL jsonLocator = new URL(DOWNLOAD_URL);
URLConnection urlConnection = jsonLocator.openConnection();
return urlConnection;
}
}
But this is somehow far-fetched. If the original methods would be changed, the test results could still be positive because with this attempt, I don't actually test the original class anymore.
How can this be done properly? (I don't want to use a framework just for this one test, so are there any design attempts to solve this in a common way?)
Another spin on Gilbert Le Blanc's suggestion, is to make the HttpClient totally ignorant of the URL by injecting it through the constructor.
public class HttpClient {
private final String url;
public HttpClient(String url) { this.url = url; }
}
You can hard code the URL (or read from a config) somewhere externally to HttpClient and inject it wherever you instantiate the client. Then in your test it will be trivial to inject a bad url.
Thanks to everybody, but I think that Gilbert Le Blanc's solution is the most preferable for that case which looks like this:
The original class:
public class HttpClient {
private final String DOWNLOAD_URL = "http://my.original.json.url";
public String readJsonDataFromUrl() throws IOException {
URLConnection urlConnection = getUrlConnection();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuffer content = new StringBuffer();
String readLine = "";
while ((readLine = reader.readLine()) != null) {
content.append(readLine);
}
return content.toString();
}
private URLConnection getUrlConnection() throws IOException {
URL jsonLocator = new URL(getConnectionString());
return jsonLocator.openConnection();
}
protected String getConnectionString() {
return DOWNLOAD_URL;
}
}
The mock object:
public class HttpClientMock extends HttpClient {
private String downloadUrl = "http://my.original.json.url";
public HttpClientMock() {
super();
}
public HttpClientMock(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
#Override
protected String getConnectionString() {
return downloadUrl;
}
}
And the working tests:
public class HttpClientTest {
private JSONParser jsonParser = new JSONParser();
#Test
public void readJsonDataFromUrlSucceeds() throws IOException, ParseException {
HttpClient httpClient = new HttpClientMock();
String jsonString = httpClient.readJsonDataFromUrl();
JSONObject jsonObject = (JSONObject)jsonParser.parse(jsonString);
assertTrue(jsonObject.size() > 0);
}
#Test(expected = IOException.class)
public void readJsonDataFromMalformedUrlFails() throws IOException, ParseException {
HttpClient httpClient = new HttpClientMock("http://malformed");
httpClient.readJsonDataFromUrl();
}
}
Related
Can you tell me why I can't see my list when I try to start it from another method? Below methods:
public class CollectionsOperation {
private List<Client> bufferedReaderClientLIst = new ArrayList<Client>();
private List<Client> emptyBoxForCf = new ArrayList<Client>();
BufferedReader bf = null;
private static final String fileName = "Clients.txt";
public List<Client> bufferedReaderCollection() throws IOException {
String line;
bf = new BufferedReader(new InputStreamReader (new FileInputStream(fileName), "UTF-8"));
while((line = bf.readLine()) != null) {
String[] split = line.split(";");
String nameCompany = split[0].substring(2);
String adress = split[1];
String phoneNumber = split[2];
String emailAdress = split[3];
Client k = new Client(nameCompany, adress, phoneNumber, emailAdress);
bufferedReaderClientLIst.add(k);
}
System.out.println(bufferedReaderClientLIst);
return bufferedReaderClientLIst;
}
public void show() throws IOException {
CollectionsOperation k = new CollectionsOperation();
k.bufferedReaderCollection();
System.out.println(bufferedReaderClientLIst);
}
Calling the method:
public static void main(String[] args) throws IOException {
CollectionsOperation k = new CollectionsOperation();
k.show();
}
And this is the result what I get:
[ MarkCompany';Ilusiana';0982882902';mark#company.com, CorporationX';Berlin';93983';X#Corporation.com]
[]
Why the second list is empty ? the method bufferedReaderCollection() returns a result and the list bufferedReaderClientLIst is available to all methods. What is wrong?
In show():
public void show() throws IOException {
CollectionsOperation k = new CollectionsOperation();
k.bufferedReaderCollection();
System.out.println(bufferedReaderClientLIst);
}
You create another CollectionsOperation object to call bufferedReaderCollection() on. This is unnecessary.
However the problem is in the last print statement where you print bufferedReaderClientList. This is printing the bufferedReaderClientList of the this instance, not k. Because you have not called bufferedReaderCollection on this, the list will be empty, hence the [] printed at the end.
Instead of creating another instance, use this:
public void show() throws IOException {
this.bufferedReaderCollection();
System.out.println(bufferedReaderClientLIst);
}
I"m given a requirement on how to test HTTP website without UI. Let says, we have a google website search functionalities (Not Web Services) and I need to test it. How to start? Can anyone give some example (JUnit)(Get/Post Method) for me to start this project. I tried reading the official documentation but found nothing about it. Thanks in advance.
You can do it with the following snippet
public class Searcher {
public String search(String searchUrl, String searchWord) throws IOException, URISyntaxException {
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
URIBuilder builder = new URIBuilder(searchUrl);
builder.setParameter("search_term", searchWord);
HttpGet request = new HttpGet(builder.build());
HttpResponse httpResponse = httpClient.execute(request);
return convertResponseToString(httpResponse);
}
}
private String convertResponseToString(HttpResponse response) throws IOException {
try (Scanner scanner = new Scanner(response.getEntity().getContent(), "UTF-8")) {
String responseString = scanner.useDelimiter("\\Z").next();
return responseString;
}
}
}
public class SearcherTest {
#Rule
public WireMockRule wireMockRule = new WireMockRule(options().dynamicPort());
#Test
public void searchTest() throws IOException, URISyntaxException {
String searchWord = "something";
String expectedResult = "Your expected result";
stubFor(get(urlPathEqualTo("/search"))
.withQueryParam("search_term", equalTo(searchWord))
.willReturn(aResponse()
.withBody(expectedResult)));
Searcher searcher = new Searcher();
String searchResult = searcher.search("http://localhost:" + wireMockRule.port() + "/search", searchWord);
verify(getRequestedFor(urlPathEqualTo("/search"))
.withQueryParam("search_term", equalTo(searchWord)));
assertEquals(expectedResult, searchResult);
}
}
it's my first question here, i've try to be the more explicit :)
I want get value from a JSON page : https://api.dailymotion.com/video/x3p6d9r?fields=onair.
I have follow a tutorial about json object.
But i want get the value "onair" and put this in a String for use a IF STRING == "XX".
This is my code :
public class notification extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
detectonline();
}
public void detectonline(){
/*
if (xx == "false") {
Do something is live is off
}
else{
Do something is live is on
}
*/
}
public static boolean checkIfOnline(String channel) throws IOException {
String channerUrl = "https://api.dailymotion.com/video/x3p6d9r?fields=onair";
String jsonText = readFromUrl(channerUrl);// reads text from URL
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(jsonText).getAsJsonObject();
return !json.get("onair").isJsonNull();
}
private static String readFromUrl(String url) throws IOException {
URL page = new URL(url);
StringBuilder sb = new StringBuilder();
Scanner scanner = null;
try{
//scanner = new Scanner(page.openStream(), StandardCharsets.UTF_8.name());
scanner = new Scanner(page.openStream());
while (scanner.hasNextLine()){
sb.append(scanner.nextLine());
}
}finally{
if (scanner!=null)
scanner.close();
}
return sb.toString();
}
}
I remake your method according what you are looking for it's one of several way to parse json data :
public static boolean checkIfOnline(String channel) throws JSONException, IOException {
String channerUrl = "https://api.dailymotion.com/video/x3p6d9r?fields=onair";
String jsonText = readFromUrl(channerUrl);// reads text from URL
JSONObject json = new JSONObject(jsonText); // You create a json object from your string jsonText
if(json.has("onair")) { // just a simple test to check the node that you need existe
boolean value = json.getBoolean("onair"); // In the url that you gave onair value is boolean type
return value;
}
return false;
}
I will create methode using your way !
public static boolean checkIfOnline(String channel) throws IOException {
String channerUrl = "https://api.dailymotion.com/video/x3p6d9r?fields=onair";
String jsonText = readFromUrl(channerUrl);// reads text from URL
JsonParser parser = new JsonParser();
String myString =json.get("onair");
return mystring;}
I'm trying to Post a JSON to a Rest service using RestAssured and it throws java.net.ConnectException error.
Since my JSON message is complex, I've made it available within the txt file.
public class PPJson {
public static void main(String[] args) throws IOException, JSONException {
BufferedReader tempreader = new BufferedReader(new FileReader("/Users/RestService/Jsonfileinput.txt"));
StringBuilder sbuilder = new StringBuilder();
String line = tempreader.readLine();
while (line != null) {
sbuilder.append(line);
line = tempreader.readLine();
}
tempreader.close();
//Initializing Rest API's URL
String APIUrl = "http://api.sample.com/api/v3/parcel/collect?apiKey={Value}";
//Initializing payload or API body
String APIBody = sbuilder.toString();
// Building request using requestSpecBuilder
RequestSpecBuilder builder = new RequestSpecBuilder().setBody(APIBody).setContentType("application/json; charset=UTF-8");
RequestSpecification requestSpec = builder.build();
//Making post request with authentication
Response response = given().authentication().preemptive().basic("","").spec(requestSpec).when().post(APIUrl);
JSONObject JSONResponseBody = new JSONObject(response.body().asString());
//Fetching the desired value of a parameter
String result = JSONResponseBody.getString("status");
System.out.println(result);
}
}
#all, the issue has been fixed, removed the references to RequestSpecs and here's the code snippet
public class ParcelPointJson {
public static void main(String[] args) throws IOException, JSONException {
BufferedReader tempreader = new BufferedReader(new FileReader("/Users/srkrish/gitTrial/pim-automation/RestService/Jsonfileinput.txt"));
StringBuilder sbuilder = new StringBuilder();
String line = tempreader.readLine();
while (line != null) {
sbuilder.append(line);
line = tempreader.readLine();
}
tempreader.close();
//Initializing Rest API's URL
String APIUrl = "http://api.staging.wow.parcelpoint.com.au/api/v3/parcel/collect?apiKey=09BH1TXV";
//Initializing payload or API body
String APIBody = sbuilder.toString();
//Making post request with authentication
Response response = given().contentType("application/json; charset=UTF-8").body(APIBody).when().post(APIUrl);
JSONObject JSONResponseBody = new JSONObject(response.body().asString());
//Fetching the desired value of a parameter
String result = JSONResponseBody.getString("parcelId");
System.out.println(result);
//Assert.assertEquals(result, "200");
}
}
I am extracting the post details of a facebook page. I extracted the json of a particular page and now I have to get id of all the posts of that page. How can I do it using facebook4j.
private static String readpage(Reader rd) throws IOException
{
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1)
{
sb.append((char) cp);
}
return sb.toString();
}
public static JSONObject readurl(String url) throws IOException, JSONException
{
InputStream is = new URL(url).openStream();
try
{
BufferedReader rd = new BufferedReader(new InputStreamReader
(is, Charset.forName("UTF-8")));
String jsonText = readpage(rd);
JSONObject json = new JSONObject(jsonText);
return json;
}
finally
{
is.close();
}
}
public static void main(String[] args) throws
IOException, JSONException, FacebookException
{
JSONObject json = readurl("https://graph.facebook.com/"+s);
}
You can obtain all the post related information of a particular page by referring the following code :
ResponseList<Post> results = facebook.getPosts(searchPost);
String userId = "";
for (Post post : results) {
obj.put("Post Id", post.getId());
obj.put("Post message", post.getMessage());
obj.put("No of likes on Post", post.getLikes().size());
obj.put("Post owner name:", post.getFrom().getName());
objArray = new JSONArray();
where obj is a JSON object.
PS:I am using eclipse kepler and facebook4j-core-2.0.2