Mockito Inject mock into Spy object - mockito

Class A {
B b;
C c;
}
Class C {
D d;
E e;
}
I want to write unit test for A but I do not want to mock methods of C. However, I do want to mock D and E in C.
I have tried these options:
Option 1:
#Mock B b;
#Mock D d;
#Mock E e;
#Spy #InjectMocks C c;
#InjectMocks A a;
Option 2:
#Mock B b;
#Mock D d;
#Mock E e;
#Spy C c = Mockito.spy(new C(d,e));
#InjectMocks A a;
Option 3:
suggestions in Mockito Inject mock into Spy object
None of the options are working for me. Will appreciate any help.

Related

Mockito Spy behaves like Mock

Environment: Java11, AWS Lambda, Dagger, JUnit5 (5.9.1), Mockito(4.8.1) (tried both mockito core & inline)
I have classes A, B and C.
C is injected to B and B is injected to A.
Method A.ma1() calls B.mb1() and B.mb1 calls C.mc1()
I just want to verify if a method "mc1" of C is called or not if I call A.ma1
Here is my structure:
#ExtendWith(MockitoExtension.class)
class Test {
#InjectMocks
A a;
#Spy
B b;
#Mock
C c;
#Test
public void test() {
a.ma1();
verify(c).mc1(any());
}
}
The problem is when A.ma1() calls B.mb1(), B.mb1() behaves like a Mock instead of a Spy.
The contents of the method never being executed during debugging, but immediately returning. I also tried to annotate B with #InjectMocks along with #Spy. It also did not work, throwing a different kind of exception.
Does anybody have any idea why does B behave like a Mock instead of a Spy?
Added after comment:
Here is the complete code: (simplified)
AService is A, InternalService is B and PanelDao is C in the above example. B's "selectMappedInternal" never executes line by line but returns immediately like a mock when called.
#ExtendWith(MockitoExtension.class)
class Test {
#InjectMocks
AService aService ;
#Spy
InternalService internalService ;
#Mock
PanelDao panelDao;
#Test
public void test() {
..
}
}
public class AService {
#Inject
InternalService internalService;
#Inject
public AService() {
}
public void processMessage(AccSqsMessage accSqsMessage) {
..
internalSet = internalService.selectMappedInternal(accSqsMessage.getCode());
..
}
}
public class InternalServiceImpl implements InternalService {
#Inject
PanelDao panelDao;
#Inject
public InternalServiceImpl() {
}
#Override
public Set<Internal> selectMappedInternal(String code) {
..
Optional<Panel> p = panelDao.findPanelByCode(code);
..
}
}
Finally able to solve it as below.
My guess about cause of the problem is implementation class "InternalServiceImpl" for interface "InternalService" could not be injected properly to unit test class (despite it is working fine when injected to a business class), so during debugging, I was not able to see execution of methods in spy object.
After spying (without annonation) an explicitly provided implementation class, everything seems solved.
#ExtendWith(MockitoExtension.class)
class Test {
#InjectMocks
AService aService ;
#InjectMocks
InternalService internalService = Mockito.spy(InternalServiceImpl.class);
#Mock
PanelDao panelDao;
#Test
public void test() {
..
}
}

Call #Autowire bean through Mockito

I have Class A and Class B. B is autowired in class A. Now I want to test the flow using mockito.
So the problem is when I tried to mock the class A and B in my test case using #InjectMock its going to class A but its not invoking class B.
I dont want to mock the class B which is autowired in class A, from A its should make call to class B and get the user details data.
#Component
public class A {
#Autowired
private B b;
public Users getUsers() {
Long id = 10;
b.getUserDetails(id);
// some Logic
}
}
#Component
public class B {
public UserDetails getUserDetails(Long id) {
// some logic to get users details ..
}
}
#RunWith(MockitoJUnitRunner.class)
public class TestA {
#InjectMocks
private A a;
#InjectMocks
private B b;
#Test
public void testA() {
Users actual = a.getUsers();
assertEquals(actual, expected());
assertNotNull(actual);
}
private Users expected() {
return new Users(); // expected users object
}
}
You should use #Spy on B in order to use real B class
#Spy
private B b;
the spy will wrap an existing instance. It will still behave in the same way as the normal instance – the only difference is that it will also be instrumented to track all the interactions with it.
You should change #InjectMocks annotation on above B to #Spy and you should add #Spy on above A also. Because you want to use B.class's and A.class's real methods. Why you need to use #Spy ?
If you use #Mock, by default for all methods, mock returns null, an empty collection or appropriate primitive / primitive wrapper value (e.g. 0, false, null, ...)
If you use #Spy then the real methods are called (unless a method was stubbed).
As a result, your creation in TestA.class should be like :
#Spy #InjectMocks private A a;
#Spy private B b;

Check inheritance in nodejs

What is the best way to check inheritance in nodejs?
I'm trying to use instanceof in a instance of a class of another module that inherits a class for this module.
file a.js
class A{
}
class B extends A{
}
var b = new B();
b instanceof A ///this work
global.c instanceof A //this doesn't work
module.exports = A;
file c.js
var A = require("./a");
class C extends A{
}
global.c = new C();
It is because of loading issue! When you load class C, it request class A and it is run before the C is defined.
I have tried it myself, if I did it as you mentioned and requested both classes, the second one comparision failed.
However this one works:
a.js
class A{
callMeLaterAligator(){
console.log(b instanceof A) ///this work
console.log(global.c instanceof A) //this now work
}
}
class B extends A{
}
var b = new B();
module.exports = A;
c.js
var A = require("./a");
class C extends A{
}
global.c = new C();
The main method
require('services/c');
const a = require('services/a');
const aInst = new a();
aInst.callMeLaterAligator();
having output
true
true
To better understand whats going on, I have created this example
a.js
console.log('Hello, I am class A and I am not yet defined');
class A{
}
class B extends A{
}
var b = new B();
console.log('Hello, I am class A and I will compare something');
console.log(b instanceof A) ///this work
console.log(global.c instanceof A) //this doesn't work
module.exports = A;
c.js
console.log('Hello, I am class C and I am not yet defined');
var A = require("./a");
console.log('Hello, I am class C and I will now try to defined myself');
class C extends A{
}
console.log('Hello, I am class C and I am defined');
global.c = new C();
console.log('Hello, I am class C and I am in global.c');
server.js
require('services/c');
Having this output
Hello, I am class C and I am not yet defined
Hello, I am class A and I am not yet defined
Hello, I am class A and I will compare something
true
false
Hello, I am class C and I will now try to defined myself
Hello, I am class C and I am defined
Hello, I am class C and I am in global.c
If you change it to require "a" first, then the C is not loaded at all
server.js change :
require('services/a');
Having this output
Hello, I am class A and I am not yet defined
Hello, I am class A and I will compare something
true
false

Is there any way to mock field of Class

Here's my case, I have a class A which has one member field b. And I want to test and in unit test, I mocked A and also need to call method f() which will invoke b's f(). But the b variable in mocked A is null, so will throw NPE, and I have no get/set method for b, so is there any way to mock b ? THanks
public static class B{
public void f() {
}
}
public static class A {
B b;
public void f() {
b.f();
}
}
If you want to mock out the b property of A in a test, you've given the b property default (package-private) access, so as long as your test is in the same package you could replace the b property directly.
#Test
public void testB() {
A underTest = new A();
B mockedB = Mockito.mock(B.class);
underTest.b = mockedB;
underTest.f();
Mockito.verify(mockedB).f();
}
As an aside, I personally dislike using package-private access to mess around with member properties for tests, and instead would recommend a dependency injection framework like Guice or Spring DI for constructor injection.
However you've described that you've mocked out A, I'd have thought if this was the case the f() method of A would do nothing - you wouldn't get a null pointer exception as the call to the mock will replace the real b property and just be a void method that does nothing. Please can you provide more details if this is the case?

What would the UML sequence diagram of the following code look like?

What is UML sequence diagram of the following code featuring a class with two inner classes where each one is instantiated once as seen in the main function?
class A{
class B{
C f(){}
}
class C{}
static void main(){
A a = new A()
B b = new B();
C c = new C();
c = b.f();
}
}
You could use an automated sequence diagram generator in Eclipse such as Diver: Dynamic Interactive Dynamic Interactive Views For Reverse Engineering. It generates both static and dynamic sequence diagrams and looks to answer your question.
I adjusted your code a bit to make it compile and used Diver to generate a sequence diagram:
That is the sequence diagram for this code:
package org.testing;
public class A {
static class B
{
C f() {
return new C();
}
}
static class C {
}
public static void main(String args[]) {
A a = new A();
B b = new B();
C c = new C();
c = b.f();
}
}

Resources