How to throw exception for a local object method call? - java

MyCode:
class LocalClass{
public getNumber(){
retunr 5;
}
}
class AnotherLocalClass{
public static getNumber(){
retunr 10;
}
}
public class A{
public int methodAa(Boolean flag, int paramValue){
return methodA(flag, paramValue);
}
private int methodA(Boolean flag, int paramValue){
int returnValue = 0;
try{
if(flag){
LocalClass localVariable = new LocalClass();
returnValue = localVariable.getNumber() + paramValue;
} else{
returnValue = AnotherLocalClass.getNumber() + paramValue;
}
return returnValue;
}catch(Exception e){
e.printStackTrace();
return 0;
}
}
}
public class ATest{
#InjectMocks
A a;
public void methodATest(){
//need help to write here
}
}
LocalClass and AnotherLocalClass are classes that contains a method that returns a value.
getNumber in AnotherLocalClass is a static method.
Class A is the main class for which I am writing ATest class.
I can only write code in methodATest. And cannot change anything in LocalClass, AnotherLocalClass or class A.
I want to write methodATest such that methodA throws an exception.
My mockito version is 1.19.10 and it cannot be changed.
And also I cannot use PowerMockito or any other new dependency.

What exceptions do you expected to occur on your code? Which parameter values will cause the exceptions? In those cases, what is the return value that you're expecting?
When you get the answers for those questions, then you gonna have to set the conditions for the exception to happen. Then your code is gonna look something like this:
public class ATest{
A a = new A();
#Test
public void methodATest(){
Boolean flag = ?;
int paramValue = ?;
int expectedReturnValue = ?;
int returnValue = a.methodAa(flag, paramValue);
assertEquals(expectedReturnValue, returnValue);
}
}
Look out for the mock method. We usually use it when we need to set a class that we don't exactly want it to run it's methods, so we mock then to return something that we need for our test to work.
You can learn more about tests with this tutorial: https://www.vogella.com/tutorials/JUnit/article.html#junittesting
----[Edit]----
If you wanted to mock the LocalClass, you were gonna need to do something like this:
#PrepareForTest({LocalClass.class, A.class})
#RunWith(PowerMockRunner.class)
public class ATest{
A a = new A();
#Test
public void methodATest(){
PowerMockito.mockStatic(LocalClass.class);
PowerMockito.when(LocalClass.getNumber()).thenThrow(new Exception());
...
}
}
But, the getNumber() method should be static for it to work.
And, since you can not use PowerMockito, it's not possible to mock the class.
----[Edit]----
#PrepareForTest({AnotherLocalClass.class, A.class})
#RunWith(PowerMockRunner.class)
public class ATest{
A a = new A();
#Test
public void methodATest(){
PowerMockito.mockStatic(AnotherLocalClass.class);
PowerMockito.when(AnotherLocalClass.getNumber()).thenThrow(new Exception());
a.methodAa(...);
...
}
}
But again, since static method belongs to the class, there is no way in Mockito to mock static methods.

Related

Getting null value after Mocking the function

class Foo {
ReturnParameters function1(int a, int b) {
function2(a, b);
}
ReturnParameters function2(int a , int b) {
// body of this function...
}
}
I am creating a Junit test with Mockito and only want to test function1() and want to mock the returns from function2()
Below is my TestCase Class
class FooTest{
Foo foo = mock(Foo.class);
#Test
public void function1test(){
Mockito.when(foo.function2(1,2)).thenReturn(new ReturnParameters(100));
ReturnParameters actualResult = foo.function1(1,2);
int expectedResult = 100;
AssertEquals(expectedResult , actualResult.getStatus());
}
}
I am getting this error message that actualResult is a null value.
Can you please help?
You are attempting to partially stub the methods in a class.
In order to do this, you must use Spy instead of Mock.
Here is some sample code (that assumes you are using Junit5 and uses doReturn.when instead of when.thenReturn):
#ExtendWith(MockitoExtension.class)
class TestFoo
{
#Spy
private Foo spyClassToTest;
#BeforeEach
public void before()
{
// stub the function 2 call. The function 1 call is still "live"
doReturn(new ReturnParameters(100)).when(spyClassToTest).function2(1, 2);
}
#Test
public void function1_descriptionOfTheTestScenario_returns100()
{
ReturnParameters actualResult;
int expectedResult = 100;
// Perform the test
actualResult = spyClassToTest.function1(1, 2);
assertNotNull(actualResult);
assertEquals(expectedResult, actualResult.getStatus());
}
}
I don't know the domain but maybe its a good idea to split your functions into different classes. It should solve this issue in a clean way. Spy should also work though.

How to wrap a command inside if-else statements with same condition used in many places

I have a class with many public methods. Each method executes a single task when a single condition is met. The conditions in all methods are exactly the same as seen below:
public class MyClass{
public ClassA method1 (arguments...){
if(condition(aLong, aString)){
return doSomething(arguments...)
}else{
throw new CustomException();
}
}
public void method2 (arguments...){
if(condition(aLong, aString)){
doSomethingElse(arguments...)
}else{
throw new CustomException();
}
}
public List<ClassB> method3 (arguments...){
if(condition(aLong, aString)){
return doSomethingDifferent(arguments...)
}else{
throw new CustomException();
}
}
private boolean condition(Long aLong, String aString){
// some code
return true;
}
}
I wanted to get rid of the repeating if...else condition by using the command pattern, so i created a class like below to wrap the actual execution inside an if else statement.
public abstract class ValidCommand<T extends Serializable> {
private BiPredicate<Long,String> predicate;
private Long aLong;
private String aString
public ValidCommand(BiPredicate<Long,String> predicate,Long aLong, String aString){
this.predicate = predicate;
this.aLong = aLong;
this.aString = aString;
}
public T execute(){
if(predicate.test(playlistId, requestUserId)){
return onExecution();
}else{
throw new CustomException();
}
}
protected abstract T onExecution();
}
and I refactored the class with the methods as below:
public class MyClass{
private BiPredicate<Long,String> predicate = (a,b) -> condition(a,b);
public ClassA method1(arguments...){
ValidCommand<ClassA> validCommand= new ValidCommand(predicate,aLong,aString){
#Override
protected Serializable onExecution() {
return doSomething();
}
};
return validCommand.execute();
}
.
.
.
}
My question is if there is a better way of doing this in Java and if is worth bothering in terms of code readability and DRY principles. Note that the number of methods inside MyClass may increase and probably all of them will share the same condition.
What about creating a utility function:
private void validate(Long aLong, String aString) {
if (!condition(aLong, aString)){
throw new CustomException();
}
}
and then adjusting your code to use it like:
public ClassA method1 (arguments...){
validate(aLong, aString);
return doSomething(arguments...);
}

How to mock external dependencies for final objects?

public class A{
private final B b;
public void meth() {
//Some code
Integer a = b.some_method(a,fun(b));
//Some code
}
private fun(int b) {
return b;
}
}
when(b.some_method(anyInt(),anyInt())).thenReturn(100)
How to mock the externally dependency when writing unit tests for class A. When i mock dependency in the above way, the value of "a" is not getting assigned to 100 as expected.
Actually the answer of Jakub is correct. Maybe you need an example to understand how to do it. Check the main method and the contructor of my example.
public class A {
private final B b;
public A(B b) {
this.b = b;
}
public void meth() {
//Some code
Integer a = b.some_method(5,fun(5));
//Some code
System.out.println(a);
}
private int fun(int b) {
return b;
}
public static void main(String[] args) {
B b = Mockito.mock(B.class);
when(b.some_method(anyInt(), anyInt())).thenReturn(100);
new A(b).meth();
}
}
With the constructor you have to set B with your mock (see the last third line in the main method).
When you run the main method you will see the output of the System.out and it is 100.
You can use powermock library to mock final object. This is the implementation from their wiki.
Testing class:
public class StateFormatter {
private final StateHolder stateHolder;
public StateFormatter(StateHolder stateHolder) {
this.stateHolder = stateHolder;
}
public String getFormattedState() {
String safeState = "State information is missing";
final String actualState = stateHolder.getState();
if (actualState != null) {
safeState = actualState;
}
return safeState;
}
}
Test snippet:
StateHolder stateHolderMock = createMock(StateHolder.class);
StateFormatter tested = new StateFormatter(stateHolderMock);
expect(stateHolderMock.getState()).andReturn(expectedState);
// PowerMock.replay(..) must be used.
replay(stateHolderMock);
You can find full sample here.
You have to change your constructor in class A to parameterized.
Create a object by passing mock object B created using powermock

Java, return method as reference

Im beginner JAVA developer. Here is a method:
private Method getSomething()
{
for (Method m : getClass().getDeclaredMethods())
{
return m;
}
return notFound;
}
private void notFound()
{
throw new Exception();
}
it doesnt matter what it does - if it finds something, then returns a Method - if not, the notFound() method itself should be returned. So the hot spot is at the return notFound; line: if I use return notFound(); then it returns its value, not the method itself. I want something like a reference/pointer. So getSomething() returns something what can be called, and if the returned method is used wrong, it should trigger that Exception - so its not an option to replace return notFound; with throw new Exception(); !
Or the 2nd option is to create a lambda method....
You need to call
this.getClass().getMethod("notFound")
to get the notFound method of the current/this object's class.
So just do this:
return this.getClass().getMethod("notFound");
More details here:
Class.getMethod
EDIT:
You can retrieve i.e. get and call private methods too via reflection.
Here is an example.
import java.lang.reflect.Method;
public class Test001 {
public static void main(String[] args) throws Exception {
Test002 obj = new Test002();
Method m = obj.getClass().getDeclaredMethod("testMethod", int.class);
m.setAccessible(true);
m.invoke(obj, 10);
m.invoke(obj, 20);
System.out.println(m.getName());
}
}
class Test002 {
private void testMethod(int x){
System.out.println("Hello there: " + x);
}
}
You need to use reflection to achieve this:
http://docs.oracle.com/javase/tutorial/reflect/
e.g. to get all methods of a given class:
Class aClass = ...//obtain class object
Method[] methods = aClass.getMethods();

Java and avoid if statements for objects with similar methods

I have 2 classes e.g. A and B.
These classes have a couple of getter/setter methods with the same name.
Now in the code I do the following:
if(obj.getClassName().equals(A.class.getName())){
A a = (A) obj;
String result = a.getInfo();
}
else if(obj.getClassName().equals(B.class.getName())){
B a = (B) obj;
String result = a.getInfo();
}
I was wondering if there is a way to call the getInfo avoiding the if statements.
Note: I can not refactor the classes to use inheritence or something else.
I was just interested if there is a trick in java to avoid the if statements.
Unless you want to use reflection, no. Java treats two types which happen to declare the same method (getInfo()) as entirely separate, with entirely separate methods.
If you've got commonality, you should be using a common superclass or a common interface that both of them inherit. You've tagged the question "design-patterns" - the pattern is to use the tools that the language provides to show commonality.
As Eng.Fouad shows, using instanceof is simpler anyway - and better, as it means your code will still work with subclasses of A or B.
You can isolate this ugliness, of course, by putting it in a single place - either with a facade class which can be constructed from either an A or a B, or by having a single method which performs this check, and then calling that from multiple places.
If you can't use inheritance and want to avoid if statements (even using instanceof)... well... the best you can do is wrap the check, cast and call in a function to avoid code duplication... otherwise there's no way to do this.
You need reflection. here is my complete example.
Class A
package a;
public class A {
String info;
public String getInfo() {
System.out.println("A getInfo");
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
Class B
package a;
public class B {
String info;
public String getInfo() {
System.out.println("B getInfo");
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
Test Class
package a;
import java.lang.reflect.Method;
public class TestAB {
public static void main(String[] args) {
A a= new A();
doSth(a);
}
private static void doSth(Object obj) {
Class c = obj.getClass();
Method m;
try {
m = c.getMethod("getInfo", new Class[] { });
String result = (String) m.invoke(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
See this line :
Class c = obj.getClass();
and
m = c.getMethod("getInfo", new Class[] { });
and
String result = (String) m.invoke(obj);
There is no if statements
If obj is declared as either A or B, you can use overloaded methods. (A good argument for type safety.) Here's a test that illustrates this:
import static org.junit.Assert.*;
import org.junit.Test;
public class FooTest {
class A {
public String getInfo() {
return "A";
}
}
class B {
public String getInfo() {
return "B";
}
}
public String doBarFor(A a) {
return a.getInfo();
}
public String doBarFor(B b) {
return b.getInfo();
}
public String doBarFor(Object obj) {
throw new UnsupportedOperationException();
}
#Test
public void shouldDoBarForA() {
A a = new A();
assertEquals("A", doBarFor(a));
}
#Test
public void shouldDoBarForB() {
B b = new B();
assertEquals("B", doBarFor(b));
}
#Test(expected = UnsupportedOperationException.class)
public void shouldFailIfDeclaredAsObject() {
Object a = new A();
assertEquals("A", doBarFor(a)); // exception thrown
}
}
How about:
String result = null;
if(obj instanceof A)
{
result = ((A) obj).getInfo();
}
else if(obj instanceof B)
{
result = ((B) obj).getInfo();
}
Refer to : this tutorial if this is what you were trying to achieve.
If obj is an Object, you'll need to check. If you don't want to use an if-statement, you can try just casting and catch the exception:
String result = null;
try {
result = ((A)obj).getInfo();
}
catch(ClassCastException e1) {
try {
result = ((B)obj).getInfo();
}
catch(ClassCastException e2) {
// do something else
}
}
Another thing you can do is make both classes implement an Interface then check for just that Interface, something like:
public interface HasInfo
{
public String getInfo();
}
Then add implements HasInfo in the class definition for A and B. Then you can just check (or cast) to HasInfo.
In Java you can use a dot as a scope resolution operator with static methods. Try something like this:
String a_info = A.getInfo();
String b_info = B.getInfo();
With objects, if two interfaces really have the same method with the same parameters and the same return type, why must they be treated differently? Take a look here for some more insight into the problem.
Good luck.

Categories