How to inject lambda method in constructor? - java

Testing class
stream list into map, where I get atribute from an element of this list
public class MyClass {
private final Map<String, IMyInterface> map;
public MyClass(final List<IMyInterface> list) {
this.map = list.stream().collect(Collectors.toMap(IMyInterface::getUniqueName, i -> i));
}
}
Test
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
#InjectMock
private MyClass instance;
#Spy
private ArrayList<IMyInterface> list;
#Mock
private A a;
#Mock
private B b;
#Before void setUp() throws Exception {
list.add(a);
list.add(b);
}
}
Or Test
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
#Spy
private ArrayList<IMyInterface> list;
#Mock
private A a;
#Mock
private B b;
private class MockedClass extends MyClass {
MockedClass(List<IMyInterface> list) {
super(list);
}
}
#Before void setUp() throws Exception {
list.add(a);
list.add(b);
}
}
How to get injected Map after execute constructor? I have to test this class and use map object
EDIT:
IMyInterface::getUniqueName()
is a method in interface
objects A and B implements IMyInterface
I want to collect injected list into map
When I add elements into list, I got it in debugging mode in my tested class, but when debugging mode is on
list.stream().collect(Collectors.toMap(IMyInterface::getUniqueName(), i -> i));
it stop

The correct answer is that should I mock A and B in my #Before
private A a;
private B b;
#Before
public void setUp() throws Exception {
a = new A(mock.Service.class); // cause it have an argument
b = new B(mock.Service.class); // cause it have an argument
list.add(a);
list.add(b);
}

Related

Using reflection in a Spy class

I have the following scenario.
public class A {
//constructors
#Value(${useMethodA:false})
private boolean isUseMethodAEnabled;
public void func() {
if(isUseMethodAEnabled()) {
a();
} else {
b();
}
}
}
//methods a() and b()
public class B {
#Autowired
private A a;
public void funcPrincipal() {
A.a();
System.out.println("Method A.a() was called");
}
}
#RunWith(MockitoJUnitRunner.class)
public class BTest {
#InjectMocks
private B b;
#InjectMocks
#Spy
private A a = new A();
#Test
public void test() {
ReflectionTestUtils.setField(a, "isUseMethodAEnabled", true);
b.funcPrincipal();
// if A is annotated with #Spy -> the "isUseMethodAEnabled" is always false
}
}
See the above comment, please.
Is there any solution to change the "isUseMethodAEnabled" value from false to true using reflection?
If I switch to #Mock instead of #Spy everything works as expected. But for my test cases, I must use #Spy + #InjectMocks.

Mocking new object method call in Junit5

I have mocked another class method called Which is called at production like new B().somemethod (arg) has return type void and newD().anymenthod() it has return type inputstream
In the test method, I am doing mocking Like donothing().when(b). somemethod ();
And
When(d.anymehod()).thenreturn(inputstream);(here inputstrem i am providing)
Here I already did #Mock B b;
#Mock D d;
Here my test case run successfully but mocked method was also called at that time.
Here I didn't want to alter the production code only test cases implementation can be altered.
class TestSystem {
#InjectMock
System sys;
#Mock
B b;
#Mock
D d;
#BeforeEach
void setup() {
MockitoAnnotation.openMocks(this);
}
#Test
testModule() {
InputStrem input = null;
when(d.anymethod()).thenReturn(inputStrem);
doNothing().when(b).somemethod();
sys.module();
}
Class System{
public void module() {
//some code .....
new B().somemethod();
inputStrem = new D().anymethod(value);
}
Class B {
public void somemethod(){
//some code .....
}
}
Class D {
public InputStrem anymethod() {
//some code ......
}
}
Try to initialise Mock like this:
#InjectMocks
private System sys;
#Mock
B b;
#Mock
D d;
private AutoCloseable closeable;
#BeforeEach
void init() {
closeable = MockitoAnnotations.openMocks(this);
}
#AfterEach
void closeService() throws Exception {
closeable.close();
}
#Test
testModule(){...}

when testing a class, check the work inside the method using a Junit and a Mockito

I have a class that I cover with tests, I am having difficulties, how can I check that inside a method addBeginList(), the operation "list.add (int)" occurs on a specific list. Using the Moсkito library, check that a specific method was called on a list in a class?
public class ClassA implements IClassA {
private List<Integer> list;
public ClassA (List<Integer> list) {
this.list = list;
}
#Override
public int addBeginList() {
long t1 = System.currentTimeMillis();
list.add(5);
long t2 = System.currentTimeMillis();
return (int) t2 - (int) t1;
}
Test class
#RunWith(MockitoJUnitRunner.class)
public class ClassATest{
private ClassA mockClassA;
private static final int EXPECTED = 0;
private static final int DELTA = 1000;
private static final int SIZE = 7000;
#Before
public void setUp() throws Exception {
mockClassA = Mockito.mock(ClassA.class);
mockClassA.initialize(SIZE);
mockClassA.addBeginList();
}
#Test
public void initialize() {
}
#Test
public void addBeginList() {
assertEquals(EXPECTED, mockClassA.addBeginList(), DELTA);
}
First step is to make sure to test the real instance of the ClassA, not a mock.
Next you can either supply to it a real list and check that it contains a certain element after, or you supply it with a mocked list and check with Mockito that specific method was called:
verify(mockedList).add(5)
I found a solution to my problem:
public class ClassA extends AbstractList<Integer> implements IClassA {///}
In test class:
private List<Integer> mockedList;
private ClassA classA;
#Before
public void setUp() throws Exception {
mockedList = Mockito.mock(ClassA.class);
classA = new ClassA(mockedList);
}
#Test
public void addBeginList() {
assertEquals(EXPECTED, classA.addBeginList(), DELTA);
verify(mockedList).add(5);
}

unit testing a method that takes a list as an argument

I need to test a method that is taking a list as an argument. Below is the sample code:
public class C
{
private int x;
private String y;
//getters and setters
}
public class B
{
public void collectC(List<C> cList)
{
for(C c : cList)
{
System.out.println("int: " + c.getX() + "String: "+ c.getY());
}
}
}
So class B is simply collecting objects of class C and iteration on it using enhanced for loop.
Now, I want to test a method of class B. Below is the testing code.
public class BTest
{
private List<C> cList;
#Mock private C c;
#InjectMocks private B b;
#Before
public void setUp()
{
cList = new ArrayList<>();
cList.add(c);
MockitoAnnotations.initMocks(this);
}
#Test
public void testCollectC()
{
Mockito.when(c.getX()).thenReturn(5);
Mockito.when(c.getY()).thenReturn("Hello There");
b.collectC(cList);
}
}
So, this is giving me error NullPointerException on System.out.println() one line where I am invoking methods on 'c' object.
I then changed the code where I mocked a list and iterator too, so now my code is working fine. But I want to know that what is the problem with above-mentioned code and why it is failing?
You have to instance c before you add it to cList otherwise cList contains a null element.
The following test passes:
public class BTest {
private List<C> cList;
#Mock
private C c;
#InjectMocks
private B b;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
cList = new ArrayList<>();
cList.add(c);
}
#Test
public void testCollectC() {
Mockito.when(c.getX()).thenReturn(5);
Mockito.when(c.getY()).thenReturn("Hello There");
b.collectC(cList);
}
}

Mockito verify no more interactions with any mock

In Mockito, is there a way to verify that there are no more interactions on any mock I have created?
For example:
public void test()
{
...
TestObject obj = mock(TestObject);
myClass.test();
verifyNoMoreInteractionsWithMocks(); <-------
}
Is there such a method?
Since verifyNoMoreInteractions take an array of object we have to find a way to get all the created mocks.
You can create this class
public class MocksCollector {
private final List<Object> createdMocks;
public MocksCollector() {
createdMocks = new LinkedList<Object>();
final MockingProgress progress = new ThreadSafeMockingProgress();
progress.setListener(new CollectCreatedMocks(createdMocks));
}
public Object[] getMocks() {
return createdMocks.toArray();
}
}
and then use it in your test :
public class ATest {
private final MocksCollector mocksCollector = new MocksCollector();
#Test
public void test() throws Exception {
A a1 = mock(A.class);
A a2 = mock(A.class);
A a3 = mock(A.class);
assertEquals("wrong amount of mocks", 3, mocksCollector.getMocks().length);
verifyNoMoreInteractions(mocksCollector.getMocks());
a3.doSomething();
verifyNoMoreInteractions(mocksCollector.getMocks()); // fail
}
}
or with annotations :
#RunWith(MockitoJUnitRunner.class)
public class A2Test {
private final MocksCollector mocksCollector = new MocksCollector();
#Mock
private A a1;
#Mock
private A a2;
#Mock
private A a3;
#Test
public void test() throws Exception {
assertEquals("wrong amount of mocks", 3, mocksCollector.getMocks().length);
verifyNoMoreInteractions(mocksCollector.getMocks());
a2.doSomething();
verifyNoMoreInteractions(mocksCollector.getMocks()); // fail
}
}
It works but it adds a dependency on mockito internal.

Categories

Resources