I have a class I need to test that has two instance of different class but same interface. This is how the codes looks like,
Class to be tested:
@Service
public class MainClass {
@Resource(name = "aClass")
private IClass instance1;
@Resource(name = "bClass")
private IClass instance2;
}
Other classes:
@Service("aClass")
public class A implements IClass {}
@Service("bClass")
public class B implements IClass {}
My Unit Test:
public MainClassTest {
@InjectMocks
private MainClass mainClass;
@Mock
private IClass instance1;
@Mock
private IClass instance2;
@Test
public void test() {...}
}
When I run the test, both instance1 and instance2 are null since they are not mocked. This doesn't happen when the interface has only one implementation.
Any idea how to handle this?
Thanks, Angelo
Java does not support "multiple inheritance" (a class can only inherit from one superclass). However, it can be achieved with interfaces, because the class can implement multiple interfaces. Note: To implement multiple interfaces, separate them with a comma (see example below).
mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called.
@MockBean with @QualifierIf an interface has more than one implementation class then to choose the exact class for dependency injection, @Qualifier annotation is used. Here we will show the demo to use @MockBean with @Qualifier annotation. Find the classes used in our unit test class.
Instead of using mock(class) here we need to use Mockito. spy() to mock the same class we are testing. Then we can mock the method we want as follows. Mockito.
@InjectMocks
is a short cut which tells Mockito to instance your MainClass
and to try to inject mocks by one of constructor injection or setter injection or property injection (in order, IIRC).
I think the behaviour you are seeing may be known behaviour for Mockito; there's an open issue describe here realting to Mockito's handling of @InjectMocks
with two instances of the same mocked type.
So, instead of relying on it, you could create the instance of MainClass
the 'old fashioned' way e.g. in a @Before
method. For example:
private MainClass mainClass;
@Before
public void setup() {
IClass instance1 = mock(IClass.class);
IClass instance2 = mock(IClass.class);
mainClass = new MainClass(instance1, instance2);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With