I want to test my method to see if it will read the file correctly. I just can't seem to wrap my head around JUnit Testing. Can someone show me how to correctly write a JUnit test for this code:
import java.io.File;
import net.sourceforge.tess4j.*;
import net.sourceforge.tess4j.util.LoadLibs;
public class ImageTest {
public static String imageService(String filePath) {
File imageFile = new File("tessImage.png");
ITesseract instance = new Tesseract();
//Let tessdata be extracted in case you dont have tessdata folder
File tessDataFolder = LoadLibs.extractTessResources("tessdata");
//Set the tessdata path
instance.setDatapath(tessDataFolder.getAbsolutePath());
instance.setLanguage("eng");
try {
String result = instance.doOCR(imageFile);
return result;
} catch (TesseractException e) {
System.err.println(e.getMessage());
return "this is an error" ;
}
}
}
Forword: your exception handling is horrific. Don't return an error message when your caller is expecting the OCR string. Stick to the JAVA style. In case of an error - throw an EXCEPTION!
Next: you never actually use the "filePath" parameter. This is clearly a bug.
You first need to ask yourself WHAT to test. Is it the "imageService" method you want to test? Then create a second class and from there, you would test your method. Within this test class, you would take an example file, call your imageService and compare the result with what you would expect. Those kind of comparisons are done with Assert-statements. Please check the jUnit docs for more detail.
Related
I have a folder in my intellij project which has some .svg files, with the path "data/system/svgfiles1"
I'm doing unit testing for a method that uses these .svg files.
When I run my test locally every test is Ok.
But, in Jenkins I get an error.
The reason for this error is that I use some .svg files locally that the test needs and they are not in jenkins.
Now, the method defines a path where the data is placed. I commented where the path is defined.
As you can see, the path is hard coded.
public Optional<String> content(final Record content, final int sides) {
final Optional<String> path = Utils.findAttachmentPathById(
"./data/" + DataController.Sides[sides], // here I get the path "data/system/svgfiles1"
content.getId()
);
if (!path.isPresent()) {
return Optional.empty();
}
Optional<String> value1 = Optional.empty();
Optional<String> value2 = Optional.empty();
try {
value2 = Optional.of(FileUtils.readFileToString(new File(path.get()), StandardCharsets.UTF_8));
} catch (IOException ioException) {
logger.error("An exception", ioException);
}
try {
value1 = Optional.of(Record.format(value2.get(), content.getData()));
} catch (Exception exception) {
logger.error("An exception", exception);
}
return value1;
}
Now I created a resource folder in the tests where I added these .svg files.
The test method is this:
#Test
public void exportZipPlateSvgContentTest() {
// prepare
Record record = new Record(recordValues); // record values are only some string values
record.setId(1L);
// expected
Optional<String> expected = Optional.of(values)
// test
Optional<String> result = platesService.content(record, 1); // this is the method under test
// run
assertEquals(expected, result
}
As you can see in the test method. The path is not given as a parameter. The path is hard coded in the content method.
Since the path is hard coded in the method. Is it possible for the method to use a different path during testing?
Like, when I test it to say use the data from "test/resources/data/svgfiles1"?
I would really appreciate any input. Please let me know to clarify anything.
If you copy your files also to src/test/resources it should work.
Another approach would be to use a configuration property to specify where the files can be found and use your application.properties and application-test.properties to put in different values for production and testing.
I am new to using Mockito test framework. I need to unit test one method which return the the string content. Also the same contents will be stored in one .js file (i.e. "8.js").
How do I verify the the string contents returned from the method is as expected as i want.
Please find the below code for generating the .js file:
public String generateJavaScriptContents(Project project)
{
try
{
// Creating projectId.js file
FileUtils.mkdir(outputDir);
fileOutputStream = new FileOutputStream(outputDir + project.getId() + ".js");
streamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8");
StringTemplateGroup templateGroup =
new StringTemplateGroup("viTemplates", "/var/vi-xml/template/", DefaultTemplateLexer.class);
stringTemplate = templateGroup.getInstanceOf("StandardJSTemplate");
stringTemplate.setAttribute("projectIdVal", project.getId());
stringTemplate.setAttribute("widthVal", project.getDimension().getWidth());
stringTemplate.setAttribute("heightVal", project.getDimension().getHeight());
stringTemplate.setAttribute("playerVersionVal", project.getPlayerType().getId());
stringTemplate.setAttribute("finalTagPath", finalPathBuilder.toString());
streamWriter.append(stringTemplate.toString());
return stringTemplate.toString();
}
catch (Exception e)
{
logger.error("Exception occurred while generating Standard Tag Type Content", e);
return "";
}
}
The output of above method writes the .js file and the contents of that file are looks something below:
var projectid = 8; var playerwidth = 300; var playerheight =
250; var player_version = 1; .....
I have written the testMethod() using mockito to test this, however i am able to write the .js file successfully using the test method, but how do I verify its contents?
Can anyone help me to sort out this problem?
As #ŁukaszBachman mentions, you can read the contents from the js file. There are a couple of things to consider when using this approach:
The test will be slow, as you will have to wait for the js content to be written to the disk, read the content back from the disk and assert the content.
The test could theoretically be flaky because the entire js content may not be written to the disk by the time the code reads from the file. (On that note, you should probably consider calling flush() and close() on your OutputStreamWriter, if you aren't already.)
Another approach is to mock your OutputStreamWriter and inject it into the method. This would allow you to write test code similar to the following:
OutputStreamWriter mockStreamWriter = mock(OutputStreamWriter.class);
generateJavaScriptContents(mockStreamWriter, project);
verify(mockStreamWriter).append("var projectid = 8;\nvar playerwidth = 300;...");
http://mockito.googlecode.com/svn/branches/1.5/javadoc/org/mockito/Mockito.html#verify%28T%29
If you persist this *.js file on file system then simply create util method which will read it's contents and then use some sort of assertEquals to compare it with your fixed data.
Here is code for reading file contents into String.
I want a java program for windows in which I can also send the print specification like Layout Orientation,Number of copies,Pages from and to,etc along with the file path to be printed.
M using This Code ,It works bt I can't provide the print Specifications?
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
public class PrintFile {
public static void fileToPrint(File fis) {
try {
Desktop desktop = null;
if (Desktop.isDesktopSupported())
{
desktop = Desktop.getDesktop();
}
desktop.print(fis);
System.out.print("Printing Document");
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
}
Check out Java Print Service API
The javax.print.attribute and javax.print.attribute.standard packages define print attributes which describe the capabilities of a print service, specify the requirements of a print job, and track the progress of the print job.
For example, if you would like to use A4 paper format and print three copies of your document you will have to create a set of the following attributes implementing the PrintRequestAttributeSet interface:
PrintRequestAttributeSet attr_set = new HashPrintRequestAttributeSet();
attr_set.add(MediaSizeName.ISO_A4);
attr_set.add(new Copies(3));
Then you must pass the attribute set to the print job's print method, along with the DocFlavor.
MediaSize.ISO.A4 or MediaSize.ISO_A4 doesn't work. Instead MediaSizeName.ISO_A4 is correct.
I have a bunch of strings in a properties file which i want to 'un-externalize', ie inline into my code.
I see that both Eclipse and Intellij have great support to 'externalize' strings from within code, however do any of them support inlining strings from a properties file back into code?
For example if I have code like -
My.java
System.out.println(myResourceBundle.getString("key"));
My.properties
key=a whole bunch of text
I want my java code to be replaced as -
My.java
System.out.println("a whole bunch of text");
I wrote a simple java program that you can use to do this.
Dexternalize.java
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Deexternalize {
public static final Logger logger = Logger.getLogger(Deexternalize.class.toString());
public static void main(String[] args) throws IOException {
if(args.length != 2) {
System.out.println("Deexternalize props_file java_file_to_create");
return;
}
Properties defaultProps = new Properties();
FileInputStream in = new FileInputStream(args[0]);
defaultProps.load(in);
in.close();
File javaFile = new File(args[1]);
List<String> data = process(defaultProps,javaFile);
buildFile(javaFile,data);
}
public static List<String> process(Properties propsFile, File javaFile) {
List<String> data = new ArrayList<String>();
Set<Entry<Object,Object>> setOfProps = propsFile.entrySet();
int indexOf = javaFile.getName().indexOf(".");
String javaClassName = javaFile.getName().substring(0,indexOf);
data.add("public class " + javaClassName + " {\n");
StringBuilder sb = null;
// for some reason it's adding them in reverse order so putting htem on a stack
Stack<String> aStack = new Stack<String>();
for(Entry<Object,Object> anEntry : setOfProps) {
sb = new StringBuilder("\tpublic static final String ");
sb.append(anEntry.getKey().toString());
sb.append(" = \"");
sb.append(anEntry.getValue().toString());
sb.append("\";\n");
aStack.push(sb.toString());
}
while(!aStack.empty()) {
data.add(aStack.pop());
}
if(sb != null) {
data.add("}");
}
return data;
}
public static final void buildFile(File fileToBuild, List<String> lines) {
BufferedWriter theWriter = null;
try {
// Check to make sure if the file exists already.
if(!fileToBuild.exists()) {
fileToBuild.createNewFile();
}
theWriter = new BufferedWriter(new FileWriter(fileToBuild));
// Write the lines to the file.
for(String theLine : lines) {
// DO NOT ADD windows carriage return.
if(theLine.endsWith("\r\n")){
theWriter.write(theLine.substring(0, theLine.length()-2));
theWriter.write("\n");
} else if(theLine.endsWith("\n")) {
// This case is UNIX format already since we checked for
// the carriage return already.
theWriter.write(theLine);
} else {
theWriter.write(theLine);
theWriter.write("\n");
}
}
} catch(IOException ex) {
logger.log(Level.SEVERE, null, ex);
} finally {
try {
theWriter.close();
} catch(IOException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
}
}
Basically, all you need to do is call this java program with the location of the property file and the name of the java file you want to create that will contain the properties.
For instance this property file:
test.properties
TEST_1=test test test
TEST_2=test 2456
TEST_3=123456
will become:
java_test.java
public class java_test {
public static final String TEST_1 = "test test test";
public static final String TEST_2 = "test 2456";
public static final String TEST_3 = "123456";
}
Hope this is what you need!
EDIT:
I understand what you requested now. You can use my code to do what you want if you sprinkle a bit of regex magic. Lets say you have the java_test file from above. Copy the inlined properties into the file you want to replace the myResourceBundle code with.
For example,
TestFile.java
public class TestFile {
public static final String TEST_1 = "test test test";
public static final String TEST_2 = "test 2456";
public static final String TEST_3 = "123456";
public static void regexTest() {
System.out.println(myResourceBundle.getString("TEST_1"));
System.out.println(myResourceBundle.getString("TEST_1"));
System.out.println(myResourceBundle.getString("TEST_3"));
}
}
Ok, now if you are using eclipse (any modern IDE should be able to do this) go to the Edit Menu -> Find/Replace. In the window, you should see a "Regular Expressions" checkbox, check that. Now input the following text into the Find text area:
myResourceBundle\.getString\(\"(.+)\"\)
And the back reference
\1
into the replace.
Now click "Replace all" and voila! The code should have been inlined to your needs.
Now TestFile.java will become:
TestFile.java
public class TestFile {
public static final String TEST_1 = "test test test";
public static final String TEST_2 = "test 2456";
public static final String TEST_3 = "123456";
public static void regexTest() {
System.out.println(TEST_1);
System.out.println(TEST_1);
System.out.println(TEST_3);
}
}
You may use Eclipse "Externalize Strings" widget. It can also be used for un-externalization. Select required string(s) and press "Internalize" button. If the string was externalized before, it'll be put back and removed from messages.properties file.
May be if you can explain on how you need to do this, then you could get the correct answer.
The Short answer to your question is no, especially in Intellij (I do not know enough about eclipse). Of course the slightly longer but still not very useful answer is to write a plugin. ( That will take a list of property files and read the key and values in a map and then does a regular expression replace of ResourceBundle.getValue("Key") with the value from Map (for the key). I will write this plugin myself, if you can convince me that, there are more people like you, who have this requirement.)
The more elaborate answer is this.
1_ First I will re-factor all the code that performs property file reading to a single class (or module called PropertyFileReader).
2_ I will create a property file reader module, that iterates across all the keys in property file(s) and then stores those information in a map.
4_ I can either create a static map objects with the populated values or create a constant class out of it. Then I will replace the logic in the property file reader module to use a get on the map or static class rather than the property file reading.
5_ Once I am sure that the application performs ok.(By checking if all my Unit Testing passes), then I will remove my property files.
Note: If you are using spring, then there is a easy way to split out all property key-value pairs from a list of property files. Let me know if you use spring.
I would recommend something else: split externalized strings into localizable and non-localizable properties files. It would be probably easier to move some strings to another file than moving it back to source code (which will hurt maintainability by the way).
Of course you can write simple (to some extent) Perl (or whatever) script which will search for calls to resource bundles and introduce constant in this place...
In other words, I haven't heard about de-externalizing mechanism, you need to do it by hand (or write some automated script yourself).
An awesome oneliner from #potong sed 's|^\([^=]*\)=\(.*\)|s#Messages.getString("\1")#"\2"#g|;s/\\/\\\\/g' messages.properties |
sed -i -f - *.java run this inside your src dir, and see the magic.
I want to print the results of my JUnit tests to a .txt file.
Following is my code:
try {
//Creates html header
String breaks = "<html><center><p><h2>"+"Test Started on: "+df.format(date)+"</h2></p></center>";
//Creating two files for passing and failing a test
File pass = new File("Result_Passed-"+df.format(date)+ ".HTML");
File failed = new File("Result_Failed-"+df.format(date)+ ".HTML");
OutputStream fstreamF = new FileOutputStream(failed, true);
OutputStream fstream = new FileOutputStream(pass, true);
PrintStream p = new PrintStream(fstream);
PrintStream f= new PrintStream(fstreamF);
//appending the html code to the two files
p.append(breaks);
f.append(breaks);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Following is my example testcase:
public void test_001_AccountWorld1() {
// Open the MS CRM form to be tested.
driver.get(crmServerUrl + "account");
nameOfIFRAME = "IFRAME_CapCRM";
PerformCRM_World1("address1_name", "address1_name", "address1_line1", "address1_postalcode", true);
assertEquals(firstLineFromForm.toString(), "");
assertEquals(secondLineFromForm.toString(), "Donaustadtstrasse Bürohaus 1/2 . St");
assertEquals(postcodeFromForm.toString(), "1220");
}
I've tried p.append() but doesn't work. Help please.
In general , you can redirect your output to file as follows :
- if you are using eclipse :
Run configuration-->Commons-->OutputFile-->Your file name
If you run form the command line , just use :
java ..... >output.txt
You're probably re-inventing the wheel here. ANT, Maven, X build tool or your CI server should be doing this for you.
When I am looking to do this, I run it command line, with a custom runner, running a custom suite. Very simple, almost no code. The suite just has the test you want to run, and the runner is below.. You can see the logic there for printing out. My code just prints out errors, but you can adapt this easily to print everything to file. Essentially you are just looking in the result object collection of failures and successes.
public class UnitTestRunner {
static JUnitCore junitCore;
static Class<?> testClasses;
public static void main(String[] args) {
System.out.println("Running Junit Test Suite.");
Result result = JUnitCore.runClasses(TestSuite.class);
for (Failure failure : result.getFailures()) {
System.out.println(failure.toString());
}
System.out.println("Successful: " + result.wasSuccessful() +
" ran " + result.getRunCount() +" tests");
}
}
I believe this functionality already exists. Read this part of JUnit's FAQ.