How to stub method using Mockito in java - java

I have a singleton class S which implements an interface I.
Singleton class has a method A which inturn calls method B.
I have to test method A.
This is my singleton Class
public class S implements I{
private static S INSTANCE = new S();
public static I getInstance(){
return INSTANCE;
}
public String methodA(){
methodB();
}
}
This is how my method looks in the test class.
public void testMethodA(){
S so = S.getInstance();
S spy = Mockito.spy(so);
Mockito.doReturn(something).when(spy).methodB(); // I have to cut the dependency of this method B, hence will stub this
String exp_value = 'X';
assertEquals(exp_value,spy.methodA);
}
The issue is, actual method B is called instsead of the stub and hence my test fails.
Could anyone help and let me know if im doing anything wrong here.

Your code with a few modifications compiles and runs as expected. Here is a self contained running example.
public class StackOverflow59960713 {
public interface I {
String methodA();
}
public static class S implements I {
private static S INSTANCE = new S();
public static I getInstance() {
return INSTANCE;
}
public String methodA() {
return methodB();
}
public String methodB() {
return "abc";
}
}
#Test
public void testMethodA() {
S so = (S) S.getInstance(); <== getInstance() returns I not S
S spy = Mockito.spy(so);
Mockito.doReturn("123").when(spy).methodB();
String exp_value = "123";
assertEquals(exp_value, spy.methodA()); <=== methodA() not methodA
}
}

Related

Verify a function is called from another function mockito

I have a class in which I would like to verify method calls
Here is a representation of my class :
public class MyClass {
public void method1(String id) {
MyClass inst = this.getParticularInstance(id);
if(inst != null) {
inst.doSomething();
}
}
public MyClass getParticularInstance(String id) {
// return a particular object or null
}
public void doSomething(String id) {
// do something
}
}
In particular, I would like to make sure that when I call method1, getParticularInstance is called, and depending of the result, doSomething is called or not.
Is it possible to test such a code with Mockito, and if yes is it the right way ?
Thank you
Spy the MyClass and use verify() to verify the method invocation
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
private MyClass myClass;
#Before
public void setUp() {
myClass = spy(new MyClass());
}
public void testMethod1() {
// Arrange
String id = "id1";
// Act
myClass.method1(id);
// Assert
verify(myClass).getParticularInstance(id);
}
}

how can I add additional implementation to an overriding subclass method while still calling superclass method

I would like to add additional implementation to an overriding subclass method without completely overriding the superclass one. This is what I got to so far, but it doesn't seem to work. I would like the output to be "superclass return" followed by "subclass return". Here's the code:
public class A {
public String send() {
return "superclass return";
}
}
public class B extends A{
public String send() {
super.send();
return "subclass return";
}
}
public class Driver {
public static void main(String[] args) {
B b = new B();
System.out.println(b.send());
}
}
Output: subclass return
Am I using the wrong syntax super.send()? The intended output should be:
superclass return
subclass return
You have lost the return value of the super send() method and that is why you cannot see it in the output. To be able to see both, you need to modify the child implementation to something like this:
public String send() {
String value = super.send();
return value + "subclass return";
}
You aren't doing anything with the return value of the super class. Try this:
public class A {
public String send() {
return "superclass return";
}
}
public class B extends A{
public String send() {
return super.send() + "subclass return";
}
}
public class Driver {
public static void main(String[] args) {
B b = new B();
System.out.println(b.send());
}
}
Or if you want the line break:
return super.send() + "\nsubclass return";

Call a method after the constructor has ended

I need to call a method after the constructor has ended, and I have no idea what is the better approach.
I have this class:
class A {
public A() {
// ...
}
public void init() {
// call after the constructor
}
}
How do I call init() after the class A has been created?
You either have to do this on the client side, as so:
A a = new A();
a.init();
or you would have to do it in the end of the constructor:
class A {
public A() {
// ...
init();
}
public final void init() {
// ...
}
}
The second way is not recommended however, unless you make the method private or final.
Another alternative may be to use a factory method:
class A {
private A() { // private to make sure one has to go through factory method
// ...
}
public final void init() {
// ...
}
public static A create() {
A a = new A();
a.init();
return a;
}
}
Related questions:
What's wrong with overridable method calls in constructors?
Java call base method from base constructor
You will need a static factory method to construct the object, call the init method, and finally return the object:
class A {
private A() {
//...
}
private void init() {
//Call after the constructor
}
public static A create() {
A a = new A();
a.init();
return a;
}
}
Notice I have made the constructor and the init() method private, so that they can only be accessed by the factory method. Client code would make objects by calling A.create() instead of calling the constructor.
What did you so far? Are you looking something like this?
Class A {
public A() {
//...
}
public void init() {
//Call after the constructor
}
}
public static void main(String[] args)
{
A a = new A();
a.init();
}
I pick up some ideas and provide an abstractable solution:
class A {
protected A() {
// ...
}
protected void init() {
// ...
}
public static <T extends A> T create(Class<T> type) {
try {
T obj = type.newInstance();
obj.init();
return obj;
} catch (ReflectiveOperationException ex) {
System.err.println("No default constructor available.");
assert false;
return null;
}
}
}
If you want to call method BEFORE constructor you can use initializer block. https://www.geeksforgeeks.org/g-fact-26-the-initializer-block-in-java/
class A {
{
init()
}
public A() {
//todo
}
private final void init() {
//todo
}
}
Why not this :
Class A {
public A() {
//... Do you thing
this.init();
}
public void init() {
//Call after the constructor
}
}

Change return value of final class in tests

Does somebody know how to change the return value of the method in the final class.
I'm trying to test the ToBeTested class and I want to get true as the result.
I tried to use Powermockito but didn't find a solution.
public final class ToBeChanged {
public static boolean changeMyBehaviour() {
return false;
}
}
public class ToBeTested {
public boolean doSomething () {
if (ToBeChanged.changeMyBehaviour)
return false;
else
return true;
}
}
I do not want to declare the ToBeChanged class as a field in the ToBeTested class.
So there is no way to change the implemented classes itself.
With the JMockit tool, the test would be like this:
#Test
public void doSomething(#Mocked ToBeChanged mock)
{
new NonStrictExpectations() {{ ToBeChanged.changeMyBehaviour(); result = true; }};
boolean res = new ToBeTested().doSomething();
assertTrue(res);
}
Hide the static dependency behind an interface. Mock the interface.
Since you don't want to have a field on your class, simply pass the interface as a method parameter (alternatively get an instance through a factory, just don't use tight coupling)
public final class ToBeChanged {
public static boolean changeMyBehaviour() {
return false;
}
}
public interface MyInterface {
boolean changeMyBehaviour();
}
public class MyInterfaceImpl implements MyInterface {
#Override
public boolean changeMyBehaviour() {
return ToBeChanged.changeMyBehaviour();
}
}
class ToBeTested {
public boolean doSomething (MyInterface myInterface) {
return !myInterface.changeMyBehaviour();
}
}
class TheTest {
#Test
public void testSomething() {
MyInterface myMock = mock(MyInterface.class);
when(myMock.changeMyBehaviour()).thenReturn(true);
new ToBeTested().doSomething(myMock);
}
}

AspectJ constructor force factory pattern

I want to change the object return from call to a constuctor
FROM
public class A {
public A(){
}
public String sayHello() {
return "hello";
}
public String foo() {
return "foo";
}
}
TO
public class AWrapped extends A {
private A wrapped;
public AWrapped() {
super();
}
public AWrapped(A pWrapped) {
wrapped=pWrapped;
}
public String foo() {
return wrapped.foo();
}
public String sayHello {
return "gday mate";
}
}
What i want to do is to change the object that is returned from a call
A a = new A();
a.sayHello() returns "gday mate"
a is an instaceof AWrapped
I understand that this would usually be done with a factory pattern but I dont have access to the code of A or the code that makes new A's. And there are 1000s of places that A can be created.
It seems that Aspectj might do the trick, but i dont know much about it, If AspectJ would do the trick how to I get around the infinite wrapping i need to know that its being consturcted from within and aspect so it doesnt wrapp it again.
Thanks for the help
Jon
If I understand you right you could do the following:
I've created three packages:
aspectj for the aspect and AWrapped.java
unknown for A.java (could also be Bytecode but then you have to use Load Time Weaving)
main to test A a = new A();
MyAspect to return the AWrapped object if a new() call is made on class A:
package aspectj;
import unknown.A;
#Aspect
public class MyAspect {
#Pointcut("call(unknown.A.new(..)) && !within(aspectj..*)")
public static void init(ProceedingJoinPoint pjp) {
}
#Around("init(pjp)")
public Object initAdvice(ProceedingJoinPoint pjp) throws Throwable{
Object ret = pjp.proceed();
return new AWrapped((A) ret);
}
}
For testing:
package main;
import unknown.A;
public class Main {
public static void main(String[] args) {
A a = new A();
System.out.println(a.sayHello());
}
}
This outputs:
gday mate

Categories

Resources