Mock non static method of a class - java

I am trying to write a test with stubbing but mocking one of the methods does not happen as expected.
class A {
public static getInstance(){
return new A();
}
public String getConn(){
return "Hello";
}
}
class B {
public String createConn(){
A instance = A.getInstance();
return instance.getConn();
}
}
My Test class:
#RunWith(PowerMockRunner.class)
#PrepareForTest(A.class)
public class TestClassB{
#Spy
B classB = new B();
#Test
public void testConn(){
PowerMockito.mockStatic(A.class);
given(A.getConn()).thenReturn("Welcome");
assertEquals("Welcome", classB.createConn());
}
I want to create a test on Class B, createConn method, and when I get the connection, instead of "Hello", I want to receive "Welcome" using mockito?

I found the solution of the problem.
PowerMockito.mockStatic(A.class);
PropertyManager mock = PowerMockito.mock(A.class);
given(A.getInstance()).willReturn(mock);
given(mock.getConn()).willReturn("Welcome");
assertEquals("Welcome", classB.createConn());

Related

How use mockito so that a call on any instance of an object returns something fixed

So I have a class like this:
public class A
{
public String methodB()
{
//do something
}
}
Now suppose I have the following code:
A a1=new A();
A a2=new A();
String b=a1.methodB();
String c=a2.methodB();
I want to mock using Mockito such that whenever this methodB() is called from any instance of class A, I get the same output, say "fixedstring".
You can do something like this:
public class Test {
#Mock
private A a;
#BeforeEach
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
// Mock A behaviour
doReturn("your-string").when(this.a).methodB();
}
#Test
// Unit tests
}
The important part is doReturn("your-string").when(this.a).methodB();.

How do you test method from extended class using Mockito?

I have a class A that extends from B. B has method called doB().
In my test, I want to return A when doB() is called.
Class B:
public String doB() {
return "B";
}
Class A:
public class A extends B {
public String doA() {
String A = doB();
return A;
}
}
In my unit test, I want to do something like:
#Mock
private A a;
#Test
public void test() {
when(a.doB()).thenReturn("PASS");
a.doB();
//check if it is "PASS"
}
However, it doesn't intercept when it calls doB(). Is this possible? If not, what is the best way to test this?
Perhaps favour composition over inheritance. In other words, instead of A extending B, A should use B. So B becomes A's collaborator.
For example:
public class B {
public String doB() {
return "B";
}
}
public class A {
private B b;
public A(B b) {
this.b = b;
}
public String doA() {
String a = b.doB();
return a;
}
}
So your unit test would look something like:
public class MyTest {
#Mock
private B b;
#InjectMocks
private A a;
#Test
public void test() {
when(b.doB()).thenReturn("PASS");
a.doA();
//check if it is "PASS"
}
}
This is an example of how TDD can contribute to good design.
Since you are mocking class A, the method will not really be executed, which means there is no call to doB inside youre mock execution.
you should either setup your mock to call the real method
when(a.doA()).thenCallRealMethod();
verify(a,times(1)).doB();
or use a Spy instead of a Mock.

Junit 5 unit test case for static method with layerig

I have a class name LookupCode which is written as below.
class LookupCode {
public static LookUpCode getInstance() {
// This part will have more code for singleton.
return new LookUpCode();
}
public Map getCodeList(String code, String label) {
// return map.
}
}
My service class ABCService using LookupCode class of method getCodeList().
class ABCService {
LookupCode().getInstance().getCodeList("123", "456")`;
}
I wrote the test for ABCService by using Junit5 and Mockito. I am getting the exceptions from mockito saying getInstance() should return LookupCode`.
#Test
void test() {
try(MockedStatic<LookupCode> mockedStatic = Mockito.mockStaticLookupCode.class)) {
mockedStatic.when(() -> LookupCode().getInstance().getCodeList("123", "456")).thenReturn(buildMap());
}
}
You should first mock the result of the static method call .getInstance() and return a mocked instance of your LookukpCode class. Next, provide the stubbing on this mocked instance:
#Test
void test() {
LookupCode mockedLookupInstance = mock(LookupCode.class);
try(MockedStatic<LookupCode> mockedStatic = Mockito.mockStatic(LookupCode.class)) {
mockedStatic.when(LookupCode::getInstance).thenReturn(mockedLookupInstance);
when(mockedLookupInstance.getCodeList("123", "456").thenReturn(yourMap):
}
}
Not sure if deep stubbing works for mocking static methods with Mockito.

How to mock method calls of some object which is passed as method parameter of method under JUnit Test

I am writing JUnit for some legacy class which I can't change. The Problem which I am facing is as follows
public class B{
public String method2() {
//fetch some data from database and return it
}
}
public class A{
public String myMethod(B b) {
return b.method2();
}
}
how can I mock the call for method2 in junit using mockito
public class B2 extends B { // so, this is, in fact, an IS-A of B
public String method2() {
return "mockedResult";
}
}
In your test, you'll now have something like this:
#Test
public void testMethod() {
A toTest = new A();
assertEquals("mockedResult", toTest.myMethod(new B2());
}
This is the very simplistic way. But I would recommend to read up on a Mocking framework, such as Mockito for more complex scenario's.
https://www.baeldung.com/mockito-series
By using Mockito, for short, it would be something like this:
public class TestClass {
#Mock
private B b;
private A toTest = new A();
#Test
public void testMethod() {
when(b.method2()).thenReturn("mockedResult");
assertEquals("mockedResult", toTest.myMethod());
}
}

How to mock nested methods using PowerMock

Assume I have two classes A and B.
Class A{
public String methodA(String name) {
B b = new B();
b.methodB(name);
}
}
Class B{
public String methodB(String name) {
return name+name;
}
}
Now I want to mock methodA which has a nested method call to Class B.I have tried writing the below TestCase but getting methodNotImplementedException.
#Test
public void testCase() {
A a = new A();
B b = PowerMock.createPartialMock(B.class, "methodB");
EasyMock.expect(b.methodB(anyString())).andReturn("HELLO PTR");
PowerMock.replayAll();
String result = a.methodA("hello ptr");
assertEquals(result, "HELLO PTRHELLO PTR");
PowerMock.verifyAll();
}
Can anybody tell how to solve nested method calls using PowerMock..??
Thanx in advance
Several issues here.
First, don't use two mocking frameworks at the same time. There's no reason to expect when creating expectations in one framework, that the other would know about it.
Second, if, as stated, you want to mock methodA, supposedly as a part of a test of something that uses A, then there's no reason to mock anything from B, since the result of methodA is mocked, and will not invoke B.
Third, mock roles, not objects. Meaning, if object C accepts an A, it shouldn't get the concrete implementation, instead it should get the interface it uses. Then in the test, you mock that interface, not a class.
Given these, if you create an interface for A, and stub the response from that interface, your test will be much simpler, and you won't have to resort to these kinds of tools.
You can accomplish your goal by doing the following. Notice the whenNew call
#Test
public void testCase() {
A a = new A();
B b = PowerMock.createPartialMock(B.class, "methodB");
EasyMock.expect(b.methodB(anyString())).andReturn("HELLO PTR");
PowerMock.expectNew(B.class).andReturn(b);
PowerMock.replay(B.class);
String result = a.methodA("hello ptr");
assertEquals(result, "HELLO PTRHELLO PTR");
PowerMock.verifyAll();
}
you will also need to add #PrepareForTest(B.class) to the test class
Finally, you will need to add the api dependency
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>1.7.3</version>
<scope>test</scope>
</dependency>
If you want to mock methodA then there is no need to do anything with class B. Just do
#Test
public void testCase() {
A a = mock(A.class);
expect(a.methodA()).andReturn("HELLO");
replay(a);
// use the mock to test something
String result = a.methodA("hello ptr");
assertEquals(result, "HELLO");
verify(a);
}
But it looks like you want to test A and mock B. That's different. First, I would recommend refactoring. Even a really basic one like
public class A{
public String methodA(String name) {
B b = newB();
b.methodB(name);
}
protected B newB() {
return new B()
}
}
That way, you won't need PowerMock at all. You can do
#Test
public void testCase() {
A a = partialMockBuilder().addMockedMethod("newB").mock(A.class);
B b = mock(B.class);
expect(a.newB()).andReturn(b);
expect(b.methodB()).andReturn("HELLO");
replay(a, b);
String result = a.methodA("HI");
assertEquals(result, "HELLO");
verify(a, b);
}
And then, if you really need for some weird reason to mock new B(), yes, using Powermock.expectNew is the solution.
I resolved this by adding PowerMock.expectNew(B.class).andReturn(b); and #Mock annotation in the Test Class`
Complete Code;
public class A {
public String methodA(String name) {
B b = new B();
return b.methodB(name);
}
}
public class B{
public String methodB(String name) {
return name+name;
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest({ A.class, B.class })
public class TestCase {
#Mock
private B b;
#Test
public void testCase() throws Exception {
A a = new A();
PowerMock.expectNew(B.class).andReturn(b);
EasyMock.expect(b.methodB(anyString())).andReturn("HELLO");
PowerMock.replay(B.class, b);
String result = a.methodA("HI");
assertTrue(result != null);
assertEquals(result, "HELLO");
PowerMock.verify(B.class, b);
}
}

Categories