Mockito test case for repository layer EntityManager chained methods - spring-boot

Repository code to be tested using Mockito:
public List<X> findAll() {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<X> criteriaQuery = criteriaBuilder.createQuery(X.class);
Root<X> policyRoot = criteriaQuery.from(X.class);
return entityManager.createQuery(criteriaQuery.select(policyRoot)).getResultList();
}
How to mock cretedQuery() and getResultList() methods of entityManger?
#Test
public void testCase() {
when(entityManager.getCriteriaBuilder()).thenReturn(new
CriteriaBuilderImpl(any()));
Query query = new QueryImpl(any(), any(), any());
when(entityManager.createQuery(anyString())).thenReturn(query);
when(query.getResultList()).thenReturn(attributeList);
}
It throws NullPointerException.

Use mocks. Make sure the entityManager is injectable in the class you try to test. For a unit test I would definitely do a test like this. It does not test the database, but it does test all the calls that are done and the general application logic. I agree you should also write an integration test that will test the 'real' database call and result.
#RunWith(MockitoJUnitRunner.class)
public class QueryTest {
#Mock
TypedQuery<X> query;
#Mock
CriteriaBuilderImpl criteriaBuilder;
#Mock
CriteriaQuery<X> criteriaQuery;
#Mock
Root<X> policyRoot;
#Mock
EntityManager manager; // This mock should be injected in the class that is been tested
#InjectMocks
TestClass sut; //System Under Test
#Test
public void test() {
when(manager.getCriteriaBuilder()).thenReturn(criteriaBuilder);
when(criteriaBuilder.createQuery(any(X.class)).thenReturn(criteriaQuery);
when(criteriaQuery.from(any(X.class)).thenReturn(policyRoot);
when(criteriaQuery.select(eq(policyRoot))).thenReturn(criteriaQuery);
when(manager.createQuery(eq(criteriaQuery)).thenReturn(query);
when(query.getResultList()).thenReturn(Collections.emptyList());
List<X> result = sut.findAll();
// now verify
verify(manager, times(1)).getCriteriaBuilder();
verify(criteriaBuilder, times(1)).createQuery(any(X.class));
// and so on
// now write your assertions
assertEquals(0, result.getSize());
}
}

Related

Spring Kafka ProducerRecord Mock Test

ProducerRecord<Key,Value> producerRecord = new ProducerRecord<>(topicName, key,value);
ListenableFuture<SendResult<Key,Value>> future = kafkaTemplate.send(producerRecord);
Test Case
#Mock
ProducerRecord<Key,Value> producerRecord;
#Mock
ListenableFuture<SendResult<Key,Value>> future;
#Mock
private KafkaTemplate<Key,Value> producer;
When am mocking send method it will return null future object
when(producer.send(producerRecord)).thenReturn(future);
Solution I Found.
I Pass any(ProducerRecord.class) so i will trigger your method and return you future object
#Mock
ListenableFuture<SendResult<Key,Value>> future;
#Mock
private KafkaTemplate<Key,Value> producer;
when(producer.send(any(ProducerRecord.class))).thenReturn(future);
Besides mocking the KafkaTemplate#send method:
when(producer.send(producerRecord)).thenReturn(future);
You should instruct your class fixture implementation to initialize the mock objects. It should be a pre-instance step as follows:
#BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
}
It is common good practice to move mock configuration (common ones) to the set-up step as well:
#BeforeEach
void setup() {
MockitoAnnotations.initMocks(this);
SendResult<Key,Value> result = Mockito.mock(SendResult.class);
when(future.get()).thenReturn(result);
when(producer.send(producerRecord)).thenReturn(future);
}

Mockito test coming back as zero

I am trying to get call method called totalmoney() to get the total money in the h2 database but it always returns 0.
#RunWith(MockitoJUnitRunner.class)
public class MoneyTests {
#InjectMocks
MoneyServiceImplementation MoneyServiceImplementation;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void getAllMoney() {
long total_money = MoneyServiceImplementation.TotalMoney();
assertEquals("2000", total_money);
}}
But it will return the right amount of 2000 by:
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("Bean.xml");
MoneyService MoneyService = (MoneyService) context.getBean("MoneyServiceImplementation");
long total_money = MoneyService.TotalMoney();
So what am i doing wrong in the test that it will not work?
Mockito is not an dependency injection framework, don't expect this shorthand utility to inject a complex graph of objectsbe it mocks/spies or real objects.
Again, note that #InjectMocks will only inject mocks/spies created using the #Spy or #Mock annotation.
There are no any #Mock or #Spy annotated beans in your test, so all of the dependencies in the created MoneyServiceImplementation are null.

How to test DaoImpl methods using Junit and Mockito

I am using spring with jdbcTemplate for my app and I want to test DaoImpl class. There is implementation for insertion, updation and retrieval operation
Dao class Method
//dummy class
public class PlayerDAOImpl implements PlayerDAO {
#Autowired
private JdbcTemplate jdbcTemplate;
public Integer getPlayer(int playerId) {
String sql = "SELECT ccount(1) FROM PLAYER WHERE
PLAYER_ID = ?";
return (jdbcTemplate. queryForObject("Query", new Object[]{playerId},
Integer.class)!=0); //here only throws exception
}
//other methods
}
and for that I have written Test class which execute successfully for insertion and updation but while retrieving it is giving nullpointer exception.
#RunWith(MockitoJUnitRunner.class)
class Test{
#InjectMocks
PlayerDAOImpl dao;
#Mock
JdbcTemplate jdbcTemplate;
#Test
public void retrieveResult(){
Mockito.when(dao.getPlayer(int playerId)).thenReturn(false);
//Assert Statement
}}
I have googled/tried but not found solution which worked for me. So how to test that method or inject jdbcTemplate so that it will succeed.
Thanks for Help!!
The problem is that you are trying to mock the class under test (PlayerDAOImpl) instead of its dependency (JdbcTemplate).
Change you mock to something like:
Mockito.when(jdbcTemplate.queryForObject(Mockito.any(), Mockito.any(), Mockito.any()).thenReturn(COUNT);
Where COUNT is an Integer, and then write your assertions on the return value of dao.getPlayer.

CrudRepository test cases without inserting data in DB

I have one repository class which which implements CrudRepository. Then in service class I have auto wired this repositary. Then in controller class I have autowired this service.
I want to write test cases of controller Class. I am using below configuration.
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class XYZControllerTest {
MockMvc mockMvc;
#Mock
private XYZController xyzController;
#Autowired
private TestRestTemplate template;
#Autowired
XYZRepository xyzRepository;
#Before
public void setup() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(xyzController).build();
}
#Test
public void testPanelShouldBeRegistered() throws Exception {
HttpEntity<Object> xyz = getHttpEntity("{\"name\": \"test 1\", \"email\": \"test10000000000001#gmail.com\","
+ " \"registrationNumber\": \"41DCT\",\"registrationDate\":\"2018-08-08T12:12:12\" }");
ResponseEntity<XYZ> response = template.postForEntity("/api/xyz", xyz, XYZ.class);
}
}
My problem is that when I run test case, data is going to insert in DB which is used for application. Can I test it without inserting data in DB.
Conceptually when we are testing services we mock repositories instead of injection.
You need to mock your repository and setup behavior for returning data.
An example :
#MockBean
XYZRepository xyzRepository;
#Test
public void test() {
// other mocks
//
when(xyzRepository.findAll()).thenReturn(Arrays.asList(new XYZ()));
// service calls
// assertions
}

Resetting Mockito mocks, provided as Spring beans, between tests?

I have a Java application that uses Spring's dependency injection. I want to mock out a bean, and verify that it receives certain method calls.
The problem is that Mockito does not reset the mock between tests, so I cannot correctly verify method calls on it.
My unit under test:
public class MyClass {
#Resource
SomeClientClass client;
public void myMethod() {
client.someMethod();
}
}
The unit test class:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = UnitTestConfig.class)
public class MyClassTest {
#Resource
SomeClientClass client;
#Test
public void verifySomething() {
// ...
Mockito.verify(client).publish();
}
}
Finally,
#Configuration
public class UnitTestConfig {
#Bean
SomeClientClass client() {
return Mockito.mock(SomeClientClass.class);
}
}
Though I could hack my way around this problem by manually resetting mocks between tests, I wonder if there's a cleaner / more idiomatic approach.
I had to add this at the start:
#BeforeEach
void setup() {
Mockito.reset(...mockBeans);
...
}
Author not explained why he needs it, I can put more details.
Combining Spring's dependency injection with Mockito in this way not the best approach.
It leads to errors, because same Mocks will be reused between different tests!
This means that verify() will work incorrectly. It will accumulate method invocations from different tests. For example you will get "Wanted 1 time:" - "But was 2 times".
Most generic solution for this in Mockito is using #InjectMocks.
This annotation doing 2 important things:
actually injecting all #Mock fields into class annotated with #InjectMocks
resets each #Mock annotated class. (so, verify() will not accumulate invocations from different tests)
Code example:
#RunWith(MockitoJUnitRunner.class)
public class SomeSpringConverterTest {
#InjectMocks
private SomethingToJsonNodeSpringConverter someSpringConverter;
#Mock
private SomethingDatamodelService someDatamodelService;
#Test
public void convertOriginalContainerTest() {
SomethingContainer someContainer = buildSomeContainer("aa", "bb");
Mockito.when(someDatamodelService.getAttributes()).thenReturn(Arrays.asList("aa", "bb"));
JsonNode node = someSpringConverter.convert(someContainer, JsonNode.class);
Mockito.verify(someDatamodelService.getAttributes());
assertTrue(node.get("aa") != null);
}
#Test
public void convertOriginalContainerTest() {
SomethingContainer someContainer = buildSomeContainer("aa", "bb");
Mockito.when(someDatamodelService.getAttributes()).thenReturn(Arrays.asList("aa", "bb"));
JsonNode node = someSpringConverter.convert(someContainer, JsonNode.class);
Mockito.verify(someDatamodelService.getAttributes());
assertTrue(node.get("bb") != null);
}
}

Resources