EasyMock still goes into implementation of a method mocked with addMockedMethod - java

I am trying to write a unit-test in Java. Due to the structure of Java class, I have to come up with a way in which whenever a constructor of a class is called, a mocked object of that class is created. I want to mock 2 methods of that class.
CallToBeMocked mockCallToBeMocked = EasyMock.createMockBuilder(CallToBeMocked.class)
.withConstructor(ArgumentA.class, ArgumentB.class, ArgumentC.class)
.withArgs(mockArgumentA, mockArgumentB, mockArgumentC)
.addMockedMethod("isProxied", ArgumentA.class)
.addMockedMethod("remoteCall", String.class, ArgumentA.class, Object.class)
.createMock();
EasyMock.expect(mockCallToBeMocked.isProxied(mockArgumentA)).andReturn(false);
EasyMock.expect(mockCallToBeMocked.remoteCall("ip-address", mockArgumentA, null)).andThrow(new Exception()).times(3);
The problem is that although I have clearly specified that isProxied and remoteCall methods have to be mocked and I have given appropriate expectations for those methods, it still starts going into the actual implementations of these methods.

It should perfectly work. So something else is going on. Here is a working example based on your code. What's different from your actual implementation?
public class PartialTest {
public interface ArgumentA { }
public interface ArgumentB { }
public interface ArgumentC { }
public static class CallToBeMocked {
public CallToBeMocked(ArgumentA a, ArgumentB b, ArgumentC c) {
}
public boolean isProxied(ArgumentA a) {
return true;
}
public int remoteCall(String ip, ArgumentA a, Object any) throws Exception {
return 0;
}
}
#Test
public void test() throws Exception {
ArgumentA mockArgumentA = createNiceMock(ArgumentA.class);
ArgumentB mockArgumentB = createNiceMock(ArgumentB.class);
ArgumentC mockArgumentC = createNiceMock(ArgumentC.class);
CallToBeMocked mockCallToBeMocked = createMockBuilder(CallToBeMocked.class)
.withConstructor(ArgumentA.class, ArgumentB.class, ArgumentC.class)
.withArgs(mockArgumentA, mockArgumentB, mockArgumentC)
.addMockedMethod("isProxied", ArgumentA.class)
.addMockedMethod("remoteCall", String.class, ArgumentA.class, Object.class)
.createMock();
expect(mockCallToBeMocked.isProxied(mockArgumentA)).andReturn(false);
expect(mockCallToBeMocked.remoteCall("ip-address", mockArgumentA, null)).andThrow(new Exception()).times(3);
replay(mockCallToBeMocked);
assertFalse(mockCallToBeMocked.isProxied(mockArgumentA));
try {
mockCallToBeMocked.remoteCall("ip-address", mockArgumentA, null);
fail("Should throw");
} catch (Exception e) { }
try {
mockCallToBeMocked.remoteCall("ip-address", mockArgumentA, null);
fail("Should throw");
} catch (Exception e) { }
try {
mockCallToBeMocked.remoteCall("ip-address", mockArgumentA, null);
fail("Should throw");
} catch (Exception e) { }
verify(mockCallToBeMocked);
}
}

If we aren't tied to EasyMock, here's a way in which the same functionality can be achieved using Mockito.
import static org.mockito.Mockito.verify;
import org.mockito.Mockito;
....
ClassToBeMocked myMock = Mockito.mock(ClassToBeMocked.class);
Mockito
.when(myMock.isProxied(any(ArgumentA.class)))
.thenReturn(false);
Mockito
.when(myMock.remoteCall(any(String.class), any(ArgumentA.class), any(Object.class)))
.thenThrow(new Exception("monkeys"));
<USE ``myMock``>
verify(myMock, times(1)).isProxied(mockArgumentA);
verify(myMock, times(3)).remoteCall("ip-address", mockArgumentA, null);

Related

Better way to continue after exceptions in java

Assuming I have to read from a file, and then construct a java object out of it.
PersonData p = new PersonData();
p.setName(readTokenAsString());
p.setAge(AgeConverter.createFromDateOfBirth(readTokenAsString())); // this throws a checked exception if the date of birth is mal-formed.
//... a list of methods that throws exception as AgeConverter
Behavior I want: If one attribute has problem, just ignore it and keep process other attributes.
Solution I can think of:
try {
p.setAge1(...);
} catch (Exception e) {
//log and ignore
}
try {
p.setAge2(...);
} catch (Exception e) {
//log and ignore
}
//repeat for each attribute
Question:
Is there better way to do this to avoid repetition? Functional style maybe?
a) What's the best approach if I cannot modify PersonData class.
b) What's the best approach if I can rewrite PersonData class.
Given your current declaration, I would do it as follows.
Define a #FunctionalInterface to which you can pass your I/O logic:
#FunctionalInterface
public interface CheckedSupplier<T> {
T getValue() throws Exception;
}
Define an utility method that consumes the #FunctionaInterface:
public static final <T> T getValueWithDefault(CheckedSupplier<T> supplier, T defaultValue) {
try {
return supplier.getValue();
} catch (Exception e){
return defaultValue;
}
}
Use the utility method as follows:
PersonData p = new PersonData();
p.setName(getValueWithDefault(() -> readTokenAsString(), "default"));
p.setAge(getValueWithDefault(() -> AgeConverter.createFromDateOfBirth(readTokenAsString()), 0));
This should do the trick regardless of weather you want modify the PersonData class or not.
If you use Java 8 you can do something like this. Create your own functional interface with one method that throws Exception
public interface MyConsumer<T> {
public void process(T t) throws Exception;
}
And create a static method to use that interface
public static <T> void setAndLogException(T value, MyConsumer<T> consumer) {
try {
consumer.process(value);
} catch (Exception e) {
// log exception
}
}
And then using it like setAndLogException(AgeConverter.createFromDateOfBirth(readTokenAsString()), p::setAge);
You can also use solution provided by this: https://stackoverflow.com/a/28659553/6648303
This solution won't complain at compile phase about checked Exceptions.
It would be something like this:
public static void ignoringExc(RunnableExc r) {
try { r.run(); } catch (Exception e) { }
}
#FunctionalInterface public interface RunnableExc { void run() throws Exception; }
and then:
PersonData p = new PersonData();
ignoringExc(() -> p.setName(readTokenAsString()));
...

Java - How to test exception which never will occur?

I have Utils class with method which throws exception when given data are incorrect.
I have also Service which uses this method, but the data are always generated in way that they will be correct during call. Data are generated by another utils class.
I understand that I should throw this exception from Utils class - but I can't throw it from Service - so I have to catch it.
How can I test this, simulate this exception?
All actions on this data are in private methods.
I want to avoid PowerMock, because I heard that it's a sign of bad design.
So the question is, how to implement this in good design?
From your description it looks like this:
class Service {
public void someMethod() {
Data data = AnotherUtils.getData();
try {
Utils.method(data); // exception never thrown
} catch(Exception e) {
// how to test this branch?
}
}
}
The goal would be something like this:
interface DataProvider {
Data getData();
}
interface DataConsumer {
void method(Data data);
}
class Service {
private final DataProvider dataProvider;
private final DataConsumer dataConsumer;
public Service(DataProvider dataProvider, DataConsumer dataConsumer) {...}
public void someMethod() {
Data d = dataProvider.getData();
try {
dataConsumer.method(data);
} catch(Exception e) {
}
}
}
This technique is called dependency injection.
Then, when testing, you can simply provide a mock implementation for this DataProvider interface that does return faulty data:
#Test(expected=Exception.class)
public void myTest() {
DataProvider badDataProvider = () -> new BadData(); // Returns faulty data
Service service = new Service(badDataProvider, Utils.getConsumer());
service.someMethod(); // boom!
}
For the non-testing code, you could simply wrap the utils classes you already have in these interfaces:
class AnotherUtils {
public static Data getData() {...}
public static DataProvider getProvider() {
return AnotherUtils::getData;
}
}
...
Service service = new Service(AnotherUtils.getProvider(), Utils.getConsumer());
Here is an approach where you want to introduce Dependency Injection, but for whatever reason you don't want to change legacy code.
Say you have some static utility method like so:
class Utils{
public static Something aMethod(SomethingElse input) throws AnException{
if(input.isValid())
return input.toSomething();
throw new AnException("yadda yadda");
}
}
And you have a class that uses that utility method. You can still inject it with a FunctionalInterface.
#FunctionalInterface
interface FunctionThrowsAnException<K,V> {
V apply(K input) throws AnException;
}
class Service {
private final FunctionThrowsAnException<SomethingElse,Something> func;
Service(FunctionThrowsAnException<SomethingElse,Something> func){
this.func = func;
}
Something aMethod(SomethingElse input){
try{
return func.apply(input);
}catch(AnException ex){
LOGGER.error(ex);
}
}
}
Then use it like this:
new Service(Utils::aMethod).aMethod(input);
To test it:
new Service(x -> { throw new AnException("HA HA"); }).aMethod(input);

Create an exception-safe wrapper of a class

I have a legacy class C1, implementing interface I, that may throw some exceptions.
I want to create a class C2, also implementing interface I, that is based on an instance of C1, but catches all exceptions and does something useful about them.
Currently my implementation looks like this:
class C2 implements I {
C1 base;
#Override void func1() {
try {
base.func1();
} catch (Exception e) {
doSomething(e);
}
}
#Override void func2() {
try {
base.func2();
} catch (Exception e) {
doSomething(e);
}
}
...
}
(Note: I could also make C2 extend C1. This does not matter for the current question).
The interface contains many functions, so I have to write the same try... catch block again and again.
Is there a way to reduce the amount of code duplication here?
You can make a Proxy, it could actually be generic
interface I1 {
void test();
}
class C1 implements I1 {
public void test() {
System.out.println("test");
throw new RuntimeException();
}
}
class ExceptionHandler implements InvocationHandler {
Object obj;
ExceptionHandler(Object obj) {
this.obj = obj;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(obj, args);
} catch (Exception e) {
// need a workaround for primitive return types
return null;
}
}
static <T> T proxyFor(Object obj, Class<T> i) {
return (T) Proxy.newProxyInstance(obj.getClass().getClassLoader(), new Class[] { i },
new ExceptionHandler(obj));
}
}
public class Test2 {
public static void main(String[] args) throws Exception {
I1 i1 = ExceptionHandler.proxyFor(new C1(), I1.class);
i1.test();
}
}

Mockito & Junit null pointer exception: name must not be null

I have been trying to run the following test using mockito and junit and I keep on getting "java.lang.NullPointerException: name must not be null"
Can anyone tell me why this is happening?
On debugging, I found out that this exception is thrown when the test executes the following statement in isStopValid(String) method:
FacilityValidationUtil facUtil = new FacilityValidationUtil();
#RunWith(MockitoJUnitRunner.class)
public class MyFormTest{
#InjectMocks MyForm form = new MyForm();
#Mock FacilityValidationUtil facUtil;
#Test
public void testIsStopValid() throws FinderException{
when(facUtil.isFacilityValid("")).thenReturn(false);
form.setOrigin("");
assertEquals(false, form.isStopValid(form.getOrigin()));
}
}
Class with method to be tested:
public class MyForm{
FacilityValidationUtil facUtil = new FacilityValidationUtil();
public boolean isStopValid(String stop){
try {
return facUtil.isFacilityValid(stop);
} catch (FinderException e) {
log.error("Error finding the stop. "+e.getCause());
return false;
}
}
}
public class FacilityValidationUtil{
private FacilityDAO facilityDao = new HibernateFacilityDAO();
public boolean isFacilityValid(String facility) throws FinderException{
boolean test;
FacilityImpl facilityImpl = facilityDao.findFacilityByNassCode(facility);
test = (facilityImpl==null)?false : true;
return test;
}
}
public class HibernateFacilityDAO extends HibernateAbstractDeltaDAO implements FacilityDAO {
public HibernateFacilityDAO() {
super(false);
}
}
Short Answer: You are trying to mock a variable (facUtil) that is local to your isStopValid method, so the mock version of this object in your test is never going to be called because you are 'newing it up" each time.
Long Answer: It looks like you are trying to mock the call to your FacilityValidationUtil class, and if this is the case, then you need to either make the class a field so that Mockito can inject the object by reflection (if this object is thread safe, which it looks like it is) or explore a mocking framework like PowerMockito that will allow you to mock a constructor (google for PowerMockito when new).
PowerMockito.whenNew(FacilityValidationUtil.class).withNoArguments().thenReturn(facUtil);
Mockito doesn't support any mocking of constructor args by default.
EDIT
If you are still having trouble, then I would suggest starting with a smaller example. I've put together one for you that works and uses the code you are trying to test (It's using inner classes though, which Mockito has some quirky rules about, but I'm just doing it to compress the example).
#RunWith(MockitoJUnitRunner.class)
public class MyFormTest {
#InjectMocks
private MyForm form = new MyForm();
#Mock
private FacilityValidationUtil facUtil;
#Test
public void testIsStopValid_false() {
when(facUtil.isFacilityValid("")).thenReturn(false);
assertEquals(false, form.isStopValid(""));
}
#Test
public void testIsStopValid_true() {
when(facUtil.isFacilityValid("")).thenReturn(true);
assertEquals(true, form.isStopValid(""));
}
public class MyForm {
private FacilityValidationUtil facUtil = new FacilityValidationUtil();
public boolean isStopValid(String stop) {
try {
return facUtil.isFacilityValid(stop);
} catch (FinderException e) {
return false;
}
}
}
public class FacilityValidationUtil {
public boolean isFacilityValid(String facility) throws FinderException {
throw new RuntimeException(facility);
}
}
public class FinderException extends RuntimeException {
public FinderException(String message) {
super(message);
}
}
}
What's really important is that your mock is not getting injected correctly. Until you get that resolved, you are going to keep getting the same error. Set a break point in your MyForm at the point you call facUtil.isFaciltyValid and look at the object. It should be a mockito object, not your class.
Good luck.

Using java reflection

I am trying to invoke a private method belonging to one class from another class using java reflection. Both these classes belong to different packages. Code sample is as below. But everytime I run the getDeclaredMethod it returns with NoSuchMethodException. How do I invoke the getCacheKey method from my class?
Thanks,
Class A
package com.abc;
public class TicketHelper
{
static String getCacheKey(String ticketString, Ticket ticket) throws TicketException, UnsupportedEncodingException, NoSuchAlgorithmException {
...
}
}
Class B
package com.def;
...
private Method method = null;
public class TicketHelper
{
...
try {
method = TicketHelper.class.getDeclaredMethod("getCacheKey", new Class[] {String.class, Ticket.class});
} catch (SecurityException e1) {
setTrace("Security exception2 " + e1.getMessage());
} catch (NoSuchMethodException e1) {
setTrace("No such method exception2 " + e1.getMessage());
}
method.setAccessible(true);
m_cacheKey = method.invoke(null, new Object[] {ticketString, ticket});
}
Is the class in com.def also called TicketHelper? In that case you need to qualify as com.abc.TicketHelper
EDIT
There are several compilation errors in the code you posted. Always try to come up with a short example that reproduces the problem; in most cases you will see you error in that process. The following works for me. It is same package, but that should not matter:
public class TicketHelperUser
{
public static void main(String[] args) throws Exception
{
for (java.lang.reflect.Method m : TicketHelper.class.getDeclaredMethods())
{
System.out.println(m);
}
java.lang.reflect.Method method = TicketHelper.class.getDeclaredMethod("getCacheKey", String.class, Ticket.class);
method.setAccessible(true);
method.invoke(null, new Object[] {"", new Ticket()});
}
}
public class TicketHelper
{
static String getCacheKey(String ticketString, Ticket ticket)
{
return "cacheKey";
}
}
public class Ticket {}
Not a solution but a test to identify the problem: get all declared methods and verify, that the getCacheKey is visible/present:
Method[] methods = TicketHelper.class.getDeclaredMethods();
for (Method method:methods) {
if (method.getName().equals("getCacheKey")) {
System.out.println(method); // <-- breakpoint and inspect the method object
}
}
Take a look at:
http://www.wikijava.org/wiki/Class_and_static_Method_Reflection_example
they are using getMethod instead getDeclaredMethod

Categories