JAVA JUnit testing using Easymock - java

`my code is as follows:enter code here
public String createDir(String X, String Y){
String dirName = null;
try {
File dir = new File(X+Y);
Path path = FileSystems.getDefault().getPath(X+Y));
File checkPath = new File(path.getParent().toString());
boolean isDirCreated = dir.mkdir();
if(isDirCreated){
dirName = path.getFileName().toString();
}else {
dirName = null;
}
}
catch(SecurityException se){
//message
}
catch(Exception se){
//message
dirName = null;
}
return dirName;
}
`My JUnit Test Case:
In this test case I have mocked the objects of path,file.
import static org.junit.Assert.*;
import static org.easymock.EasyMock.expect;
import java.io.File;
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import org.easymock.Mock;
import org.junit.Test;
import com.Users.Folder.Utilities;
public class UtilitiesTest {
#Mock
Utilities Utils;
#Mock
File dir,checkPath;
#Mock
Path path;
#Test
public void testCreateDir() throws Exception {
expect(dir).andReturn(new File("C:\\Users\\sasank\\Desktop\\Docs\\Docs_docready"));
expect(path).andReturn(FileSystems.getDefault().getPath("C:\\Users\\sasank\\Desktop\\Docs\\Docs_docready"));
expect(checkPath).andReturn(new File("C:\\Users\\sasank\\Desktop\\Docs"));
replay(dir,path,checkPath);
assertEquals(true, isDirCreated); //isDirCreated cannot be resolved to a variable
verify(dir,path,checkPath);
assertEquals("Docs_docready", imiUtils.dirName); // dirName cannot be resolved or is not a field
}
`dirName is also a boolean type.
what my code does is it creates a new directory in the input directory.

The "expect" method expects a call for a method from an object, which is replaced by returning value when you call the "andRetuns()". It is used for mocking classes/interfaces behaviors and does not process plain values.
For values comparison, you should use "assertEquals()" or, in your case "assertTrue()" methods in JUnit.
Simply do:
assertTrue(isDirCreated);
or
assertEquals(true, isDirCreated);
in your tests to verify the condition.
EDIT:
Seeing your code and how it behaves, here are some comments:
I think you don't need Mocks;
For a better understanding about what Mocks are and how they behave, you should read: http://easymock.org/getting-started.html
"isDirCreated" is a local variable and is never visiblie outside of "createDir" method. If you want it visible, you should create an attribute in your class and write a getter instead;
A simpler way to do your test is (assuming that "createDir" method is in a class named "Dir". If not, simply replace "Dir" with your current class name):
#Test
public void testCreateDir() throws Exception {
Dir dir = new Dir();
String directory = dir.createDir("c:/", "test_dir");
assertNotNull(directory); // this one checks if your method returned the correct path
File file = new File(directory);
assertTrue(file.exists()); // this one checks if your method created correctly you directory
}
Hope this helps.

Related

How do I change the value of a java Path object?

Below, I am trying to change the value of the Path object there using the setSoundPath() method. I cannot find any documentation to say this is possible.
I am trying to create a class that will create a copy of a file at a specified path and put the copy in the specified folder. I need to be able to change the name of the path though, because I want to create the sound object with an initial placeholder file path.
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.io.IOException;
import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;
class Scratch {
public static class Sound extends Object{
private Path there;
StringProperty tests = new SimpleStringProperty(this, "test", "");
public Sound(){
this.there = Paths.get("C:\\Users\\HNS1Lab.NETWORK\\Videos\\JuiceWRLD.mp3");
}
public void setSoundPath(String SoundPath) {
this.tests.setValue(SoundPath);
this.there = Paths.get(this.tests.toString());
}
}
public static void main(String[] args) {
Sound test = new Sound();
test.setSoundPath("C:\\Users\\HNS1Lab.NETWORK\\Music\\Meowing-cat-sound.mp3");
test.copySound();
System.out.println("Path: " + test.getSoundPath().toString());
}
}
They are immutable:
Implementations of this interface are immutable and safe for use by
multiple concurrent threads.
(from: https://docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html)
You can create new Path objects that point to your path.

Loading a class from an external jar

This is my first java program, so please excuse me if its too naive.
I have a 3rd party jar. I want to instantiate a class in the jar and be able to use its methods. Some details about the class in the jar:
Class File: rediff.inecom.catalog.product.CSVAPI
Constructor: CSVAPI()
Method: UpdateCSVAPI(key, csvpath)
Return: String
I have written the following program:
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.IOException;
class MyLoaderClass{
public void myLoaderFunction(){
File file = new File("vendorcatalogapi.jar");
try {
URL url = file.toURI().toURL();
URL[] urls = new URL[]{url};
ClassLoader cl = new URLClassLoader(urls);
Class cls = cl.loadClass("rediff.inecom.catalog.product.CSVAPI");
Object cls_object = cls.newInstance();
System.out.println(cls_object);
String output = cls_object.UpdateCSVAPI(12345,"myfile.csv");
System.out.println(output);
System.out.println("try");
}
catch (Exception e) {
System.out.println("catch");
e.printStackTrace();
}
}
public static void main(String args[]){
new MyLoaderClass().myLoaderFunction();
}
}
I am trying to compile it using:
javac -cp vendorcatalogapi.jar temp.java
But I am getting the following error:
temp.java:17: error: cannot find symbol
String output = cls_object.UpdateCSVAPI(12345,"myfile.csv");
^
symbol: method UpdateCSVAPI(int,String)
location: variable cls_object of type Object
1 error
Looks like the object is not correctly initialized. Please can someone help me with the correct way of doing it
If this is your first java program, then loading the class dynamically is probably overkill. Just use it normally and let the default class loader load it:
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.io.IOException;
import rediff.inecom.catalog.product.CSVAPI;
class MyFirstClass{
public void myFunction() {
CSVAPI cvsapi = new CSVAPI();
System.out.println(cvsapi);
String output = cvsapi.UpdateCSVAPI(12345,"myfile.csv");
System.out.println(output);
System.out.println("Success!");
}
public static void main(String args[]){
new MyFirstClass().myFunction();
}
}
Compile (note that the source code file name must match the class name):
javac -cp vendorcatalogapi.jar MyFirstClass.java
Run:
java -cp .:vendorcatalogapi.jar MyFirstClass (on Unix based)
java -cp .;vendorcatalogapi.jar MyFirstClass (on Windows)
You have to let the compiler know that cls_object is an instance of CSVAPI. If you don't, you can only use the object methods (toString, equals, etc.).
To do this, you can do the following:
rediff.inecom.catalog.product.CSVAPI cls_object = (rediff.inecom.catalog.product.CSVAPI) cls.newInstance();
Please, note that you need to have CSVAPI in your classpath!
Object class doesnt know the methods of rediff.inecom.catalog.product.CSVAPI class.
Class cls = cl.loadClass("rediff.inecom.catalog.product.CSVAPI");
Object cls_object = cls.newInstance();
So, explicit casting is required
rediff.inecom.catalog.product.CSVAPI object =
(rediff.inecom.catalog.product.CSVAPI) cls.newInstance();
will do the job.

jMock "unexpected invocation" for a method that I have a oneOf(instance).method() expected

I can't seem to figure out what I'm doing wrong here:
This is the method I'm testing:
public List<Mo> filterDuplicatesByName(List<Mo> dbMos) {
List<String> names = Lists.newArrayList();
for(Mo mo : dbMos) {
try {
String name = mo.getName();
if(names.contains(name)) {
dbMos.remove(mo);
} else {
names.add(name);
}
} catch (DataLayerException ex) {
dbMos.remove(mo);
}
}
return dbMos;
}
And this is my test class:
package com.rondavu.wt.service.recommendations;
import com.google.common.collect.Lists;
import com.rondavu.data.api.Mo;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.lib.legacy.ClassImposteriser;
import org.junit.Before;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class RecommendationsUtilsTest {
Mockery context = new Mockery();
RecommendationsUtils recommendationsUtils = new RecommendationsUtils();
final Mo mo = context.mock(Mo.class);
#Test
public void testFilterDuplicatesByName_oneMo() throws DataLayerException {
List<Mo> input = Lists.newArrayList(mo);
List<Mo> expected = Lists.newArrayList(mo);
context.checking(new Expectations() {{
oneOf (mo).getName(); will(returnValue("Mo 1"));
}});
List<Mo> actual = recommendationsUtils.filterDuplicatesByName(input);
context.assertIsSatisfied();
assertEquals(expected, actual);
}
}
When I run the test I get this output:
unexpected invocation: mo.getName()
no expectations specified: did you...
- forget to start an expectation with a cardinality clause?
- call a mocked method to specify the parameter of an expectation?
what happened before this: nothing!
[stack trace]
I'm pretty new to jMock, and Java is not my strongest language in general but I thought that my oneOf (mo).getName() would make it expect that invocation. What am I doing wrong here?
Though it's not clear why at this point, it seems like Mockery is checking a different instance of mo compared to the one you're defining the expectations to. Try inserting context.mock(Mo.class) in the same local scope as the test case (or in an #Before method) and see if that fixes things.

How to run a jar file from a separate jar file? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Execute another jar in a java program
Basically I want to run an external .jar from the one I'm working on now.
I.e. I want to run foo.jar from bar.jar
I've tried using Runtime and Process to execute "java -jar foo.jar", but it opens foo.jar and then it closes immediately. Any tips?
The easiest solution (as Thorn pointed out) would be to have the jar as a build-time dependency and invoke it statically from your code:
ExternalJarMainClass.main(new String[]{"arguments", "to", "main"});
But if that is not possible, you can use a URLClassLoader to load the jar dynamically. If the jar is indeed runnable, then you can read the main class from META-INF/MANIFEST.MF and invoke main via reflection.
This is a different approach from creating a separate process, as the external code will run in the same process as your application. Perhaps this is desirable, perhaps not - that depends on the situation.
Below's a (hastily written and flawed) sample helper class that does just that.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JarRunner {
private final Method entryPoint;
public JarRunner(File jarFile) throws
ClassNotFoundException,
IOException,
NoSuchMethodException {
URL jarUrl = jarFile.toURI().toURL();
URLClassLoader loader = URLClassLoader.newInstance(
new URL[]{jarUrl});
URL manifestUrl = loader.findResource("META-INF/MANIFEST.MF");
String manifest = resourceToString(manifestUrl);
Class<?> clazz = loader.loadClass(findMainClassName(manifest));
entryPoint = clazz.getMethod("main", String[].class);
}
public void run(String[] argsToMain) throws
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException {
entryPoint.invoke(null, (Object) argsToMain);
}
private static String resourceToString(URL url) throws IOException {
InputStream contentStream = url.openStream();
try {
BufferedReader r = new BufferedReader(
new InputStreamReader(contentStream));
StringBuilder sb = new StringBuilder();
String line = null;
do {
line = r.readLine();
if (line != null) {
sb.append(line).append('\n');
}
} while (line != null);
return sb.toString();
} finally {
contentStream.close();
}
}
private static String findMainClassName(String manifest) {
Matcher m = MAIN_CLASS_PATTERN.matcher(manifest);
if (m.find()) {
return m.group(1);
}
return null;
}
private static final Pattern MAIN_CLASS_PATTERN =
Pattern.compile("Main-Class: (.+)");
}
Sample usage:
JarRunner jr = new JarRunner(new File("path/to/MyJar.jar"));
jr.run(new String[]{"arg1", "arg2"});
Can you run foo.jar directly? Does it have a manifest with a main method?
I am guessing that you can. So you want to launch the main method inside of a class like foo.Main
Option 1: Include foo.jar in the classpath. If you are using an IDE, then this just means adding foo.jar as a library. Now you are free to import the package (lets call the package foo) and launch your second java program from a single line of Java code:
foo.Main.main(null);
Most likely you would want to do this in a separate thread:
class FooRunner extends Thread {
public void run() {
foo.Main.main(null);
}
}
and then you would launch with this:
FooRunner secondaryApp = new FooRunner();
secondaryApp.start();
Option 2
You can load the classes in the Foo package at runtime using a class loader.
See the Javadocs for java.lang.ClassLoader and this example of a CustomClassLoader
Check java -jar foo.jar runs correctly from command line. Also ensure java is there in the path. It may be better to provide absolute path to java.exe in the arguments.
Please consider using ProcessBuilder instead of Runtime.

not able to include package created by own in java

I have written a program that checks a data set and provides a result, i.e. if a climate condition is given for 1000 days as data set to the program it will find any deviation in the program and provide as result that major deviation.
package main;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import faster94.*;
import rules_agarwal.*;
import algo_apriori.*;
import context_apriori.*;
import itemsets.*;
public class MainTestAllAssociationRules {
public static void main(String [] arg){
ContextApriori context = new ContextApriori();
try {
context.loadFile(fileToPath("ds1.txt"));
}
catch(Exception e)
{
e.printStackTrace();
}
/*catch (IOException e) {
e.printStackTrace();
}*/
context.printContext();
double minsupp = 0.5;
AlgoApriori apriori = new AlgoApriori(context);
Itemsets patterns = apriori.runAlgorithm(minsupp);
patterns.printItemsets(context.size());
double minconf = 0.60;
AlgoAgrawalFaster94 algoAgrawal = new AlgoAgrawalFaster94(minconf);
RulesAgrawal rules = algoAgrawal.runAlgorithm(patterns);
rules.printRules(context.size());
}
public static String fileToPath(String filename) throws UnsupportedEncodingException{
URL url = MainTestAllAssociationRules.class.getResource(filename);
return java.net.URLDecoder.decode(url.getPath(),"UTF-8");
}
}
The above is the main program. There are seven files and I have created by own package, but when I run this program as a whole I cannot run it. It complains that a package is missing. i have ready provided all the seven files.
Can any one be able to run those files?
Directory tree has to reflect package tree.
So if you have a class in a package named main you class file must be in a directory named main under the working directory. So if you execute from bin/ your class must be in bin/main.
Hope this helps
Edit
The directory tre has to look like this.
bin/
-----faster94/
--------------Classes or Subpackage
-----rules_agarwal/
-------------------Classes or Subpackage
-----algo_apriori/
------------------Classes or Subpackage
-----context_apriori/
---------------------Classes or Subpackage
-----itemsets/
--------------Classes or Subpackage
-----main/
----------MainTestAllAssociationRules and other classes or subpackages
To run this use java main.MainTestAllAssociationRules in the root (bin/) directory

Categories