Junit Mockito test cases using Jupiter for Hazelcast Jet Pipiline - spring-boot

I am trying to write the Junit test cases for the below hazelcast Jet Pipeline.
My component:
#Component
public class UserJetJob extends AbstarctJetJob {
private static final String TABLE_NAME = "User";
#Autowired
private ClientConfig clientConfig;
#Value("${jdbc.connection_url}")
private String connectionUrl;
#Override
public Pipeline buildPipeline() {
Pipeline p = Pipeline.create();
p.readFrom(Sources.jdbc(connectionUrl,
"SELECT * FROM " + TABLE_NAME,
UserJetJob::buildUser))
.map(a -> Util.entry(a.getId(), a))
.writeTo(Sinks.remoteMap("userMap", clientConfig));
return p;
}
}
I am writing a JUnit test case for the method public Pipeline buildPipeline() but it's failing due to the resultset.
#ExtendWith(MockitoExtension.class)
public class UserJetJobTest extends JetTestSupport {
#InjectMocks
UserJetJob userJetJob;
#Mock
private JetInstance jet;
#Mock
private ClientConfig clientConfig;
#Test
public void buildPipelineUser() {
Pipeline p = Mockito.mock(Pipeline.class);
// Mockito.when(p.readFrom(Sources.jdbc(Mockito.anyString(), Mockito.anyString(), Mockito.eq(ResultSet.class))).then
userJetJob.buildPipeline();
}
}
Could you please help me with how to write JUnit test cases?

Related

#MockBean with Junit Jupiter concurrent mode

I am trying to use
junit.jupiter.execution.parallel.mode.default=concurrent
along with #MockBean from Spring Boot. However, the tests starts to fail when I set to concurrent mode. I tried setting
#MockBean(reset = MockReset.NONE)
However, it also does not help. Seems like mocked bean is reinitialized / reset even though MockReset.NONE is set.
Is that possible to use #MockBean allow with concurrent mode or is it a known limitation?
Bean I am mocking:
#Service
public class SampleService {
public Mono<String> processCall(String call) {
return Mono.just("ok");
}
}
The controller I am testing:
#RestController
#RequiredArgsConstructor
public class SampleController {
private final SampleService sampleService;
#PostMapping("/call")
public Mono<String> processCall(#RequestBody String body) {
return sampleService.processCall(body);
}
}
And tests:
#ExtendWith(SpringExtension.class)
#WebFluxTest(SampleController.class)
#ContextConfiguration(classes = {SampleController.class})
class SampleTest {
#MockBean(reset = MockReset.NONE)
private SampleService sampleService;
#Autowired
private WebTestClient webTestClient;
#Test
void givenSampleServiceWorksFineExpectOkResponse() {
String randomBody = "1234";
when(sampleService.processCall(randomBody)).thenReturn(Mono.just("ok"));
callService(randomBody).expectStatus().isOk().expectBody(String.class).isEqualTo("ok");
}
#Test
void givenSampleServiceFailedExpectErrorResponse() {
String randomBody = "9876";
when(sampleService.processCall(randomBody))
.thenReturn(Mono.error(new RuntimeException("error")));
callService(randomBody).expectStatus().is5xxServerError();
}
private ResponseSpec callService(String body) {
return webTestClient
.post()
.uri(
uriBuilder ->
uriBuilder
.path("/call")
.build())
.bodyValue(body)
.exchange();
}
}
I set concurrent mode for Jupiter in file junit-platform.properties:
junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default=concurrent
junit.jupiter.execution.parallel.config.strategy=dynamic

Spring boot rest api mockito + mockmvc persistence

I would like to create Test for my rest controller:
#Controller
#RequestMapping("/v2/api/show/project")
public class ApiAccessController {
private final ApiAccessService apiAccessService;
#Autowired
ApiAccessController(ApiAccessService apiAccessService){
this.apiAccessService = apiAccessService;
}
#PutMapping(value = "/{id}/apikey")
public ResponseEntity<ApiKeyResponse> generateApiKey(#PathVariable("id")Long id, Principal principal) {
return apiAccessService.generateApiKey(id, principal.getName());
}
}
My test looks as follow:
#RunWith(SpringJUnit4ClassRunner.class)
public class ApiAccessControllerTest {
private MockMvc mockMvc;
Principal principal = new Principal() {
#Override
public String getName() {
return "TEST_PRINCIPAL";
}
};
#InjectMocks
ApiAccessController apiAccessController;
#Mock
ProjectRepository projectRepository;
#Before
public void setUp(){
mockMvc = MockMvcBuilders.standaloneSetup(apiAccessController).build();
}
#Test
public void testGenerateApiKey() throws Exception {
Project project = new Project();
project.setId((long) 1);
project.setName("test");
project.setDescription("testdesc");
project.setCiid("ciid");
when(projectRepository.save(any(Project.class))).thenReturn(project);
mockMvc.perform(MockMvcRequestBuilders.put("/v2/api/show/project/" + project.getId() +"/apikey").principal(principal))
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
Which is ment to create project and then run generateApiKey on this project, however I get NullpointerException looking like mocked controller cannot find created entity
could anyone please point me in the right direction as I am just starting with testing?
You should mock ApiAccessService instead of ProjectRepository.
Have a look at the code:
#RunWith(SpringJUnit4ClassRunner.class)
public class ApiAccessControllerTest {
private MockMvc mockMvc;
private Principal principal = () -> "TEST_PRINCIPAL";
#InjectMocks
private ApiAccessController apiAccessController;
#Mock
private ApiAccessService apiAccessService;
#Before
public void setUp() {
mockMvc = MockMvcBuilders.standaloneSetup(apiAccessController).build();
}
#Test
public void testGenerateApiKey() throws Exception {
long id = 1L;
when(apiAccessService.generateApiKey(id, principal.getName())).thenReturn(new ApiKeyResponse(111L));
mockMvc.perform(MockMvcRequestBuilders.put("/v2/api/show/project/{id}/apikey", id).principal(principal))
.andExpect(MockMvcResultMatchers.status().isOk());
}
}
If you want to create integration test, that tests ApiAccessController -> ApiAccessService -> ProjectRepository integration you need to load your context (use for example #SpringBootTest).
Also you need to fix controller, use ResponseEntity.ok(...) :
#PutMapping(value = "/{id}/apikey")
public ResponseEntity<ApiKeyResponse> generateApiKey(#PathVariable("id") Long id, Principal principal) {
return ResponseEntity.ok(apiAccessService.generateApiKey(id, principal.getName()));
}
You can find really good examples of all test types in this repository MVC tests examples
The Mock you are creating is not referenced in the Controller. The Service you reference in the Controller is not part of your test setup. Therefore any access to the Service will cause a NullPointerException as the Service is not set.

Unable to mock a method with Mockito and Spring

I have a class JobDelegate for which i am writing unit tests using mockito. I am unable to mock the HTTPOperations class. I have tried using setter injection from test class as well. But it does not work. Below the latest revision of the code. I tried using Power mock. but none of them was helpful. I am unable to predict which is going wrong.
Unit Test code
#ContextConfiguration(locations= "file:src/main/webapp/WEB-INF/spring-
context.xml")
#RunWith(SpringJUnit4ClassRunner.class)
//#RunWith(PowerMockRunner.class)
/#PowerMockIgnore({ "javax.xml.*", "org.xml.*", "org.w3c.*" })
//#PrepareForTest({ HTTPOperations.class})
public class JobSubmissionDelegateTest{
private static Logger LOGGER = null;
private JobDelegate jobDelegate ;
private JobManager jobImpl;
#InjectMocks
private HTTPOperations operations;
//#Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
#Before
public void setupTests() {
jobDelegate = new JobDelegate();
jobManager = new DBJobManagerImpl();
operations = new HTTPOperations();
jobManager.setHttpOperations(operations);
jobSubmissionDelegate.setJobImpl(jobManager);
//HTTPOperations httpOperationsSpy =spy(HTTPOperations.class);
//doReturn("{\"response\":\"{\\\"run_id\\\":32423423}\\n\"}").when(myClassSpy).method1();
MockitoAnnotations.initMocks(this);
}
#Test
public void testExecuteJob() throws IOException {
// PowerMockito.mockStatic(HTTPOperations.class);
Mockito.when(operations.submitHttpPostRequest(any(), anyString())).thenReturn("{\"response\":\"{\\\"run_id\\\":32423423}\\n\"}");
//System.out.println("==>"+operations.submitHttpPostRequest(null, ""));
...........
int runID = jobDelegate.executeJob(jobDetails);
System.out.println("Run ID here " + runID);
}
}
public class JobDelegate {
// This is an interface.. and the implementation is passed from spring-
context.xml
#Autowired
private JobManager jobImpl;
public int executeJob(JobDTO jobDto) {
............
return jobImpl.runBatchJob(jobDto);
}
}
public class DBJobManagerImpl implements JobManager{
#Autowired
private URIUtils uriUtils;
#Autowired
private HTTPOperations httpOperations;
#Override
public int runBatchJob(JobDTO jobDto) throws Exception {
UriComponentsBuilder uri = uriUtils.createURI(ConfigUtil.getUrI());
String response = httpOperations.submitHttpPostRequest(uri, runSubmitJson);
System.out.println("Response ==> " +response);
.................
}
}
I was able to resolve the issue using PowerMock.
Below the code
#RunWith(PowerMockRunner.class)
#ContextConfiguration(locations= "file:src/main/webapp/WEB-
INF/Enrichment_Context.xml")
#PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)
#PowerMockIgnore({ "javax.xml.*", "org.xml.*", "org.w3c.*",
"javax.management.*" })
#PrepareForTest({ HTTPOperations.class})
public class JobDelegateTest {
#Autowired
private JobDelegate jobSubmissionDelegate;
#Test
public void testExecuteJob() throws IOException {
PowerMockito.mockStatic(HTTPOperations.class);
PowerMockito.when(HTTPOperations.submitHttpPostRequest(Mockito.any(),
Mockito.anyString())).thenReturn("{\"response\":\"{\\\"run_id\\\":32423423}\\n\"}");
...................
int runID = jobSubmissionDelegate.executeJobSubmission(jobDetails);
}
}

How to write junit test for below code using mockito?

Hi I am new to groovy unit test using mockito.I am trying to figure how to write test case for daoImpl calss without really updating or inserting in database.
below is my code.
#Component
public class TransactionDAOImpl implements TransactionDAO {
#Autowired
StringUtilities stringUtilities;
#Autowired
private TransactionRepository transactionRespository;
#Override
#Transactional
public String create(List<DepositoryTransaction> depositoryTransaction) {
List<DepositoryTransaction> dep = transactionRespository.saveAll(depositoryTransaction);
LOGGER.debug("Recieved atm transaction : {} = {}", dep);
if (dep != null && !dep.isEmpty())
return stringUtilities.SUCCESS;
else
return stringUtilities.FAILURE;
}
}
#RunWith(MockitoJUnitRunner.class) // org.mockito.runners.MockitoJUnitRunner is deprecated so use org.mockito.junit.MockitoJUnitRunner instead
public class TransactionDAOImplTest{
#InjectMocks
private TransactionDAOImpl transactionDAOImpl;
#Mock
StringUtilities stringUtilities;
#Mock
private TransactionRepository transactionRespository;
List<DepositoryTransaction> depositoryTransaction=new ArrayList<>();
#Test
public void testCreateSaveAllNullReturn(){
when(transactionRespository.saveAll(depositoryTransaction)).thenReturn(null);
assertThat(transactionDAOImpl.create(depositoryTransaction)).isEqualTo(stringUtilities.SUCCESS); // i do not khnow if this is an enum ?
}
#Test
public void testCreateSaveAllEmptyReturn(){
when(transactionRespository.saveAll(depositoryTransaction)).thenReturn(new ArrayList<>());
assertThat(transactionDAOImpl.create(depositoryTransaction)).isEqualTo(stringUtilities.SUCCESS); // i do not khnow if this is an enum ?
}
#Test
public void testCreateSaveAllNotEmptyAndNotNullReturn(){
DepositoryTransaction obj=new DepositoryTransaction();
depositoryTransaction.add(obj);
when(transactionRespository.saveAll(depositoryTransaction)).thenReturn(depositoryTransaction);
assertThat(transactionDAOImpl.create(depositoryTransaction)).isEqualTo(stringUtilities.FAILURE); // i do not khnow if this is an enum ?
}
}

Using #SpyBean with #Qualifier Spring Boot Test

I have 2 DataSources in my app.
So, to get the required JdbcTemplate, i use #Qualifier. But, when i do like below, the test runs... but stays waiting indefinitely, if there is any use of JdbcTemplate in the "Method Under Test".
#Service
#Transactional
public class SampleDatabaseService {
#Autowired
#Qualifier("firstDbJdbcTemplate")
private JdbcTemplate firstDbJdbcTemplate;
#Autowired
#Qualifier("secondDbJdbcTemplate")
private JdbcTemplate secondDbJdbcTemplate;
#Cacheable("status")
public Map<String, Device> readAllValidDeviceStatus() {
Map<String, Device> allDeviceStatuses = new HashMap<>();
//Stops at below line indefinitely if "SpyBean" is used
List<StatusDetail> statusDetails = firstDbJdbcTemplate
.query(SqlQueries.READ_DEVICE_STATUS, BeanPropertyRowMapper.newInstance(StatusDetail.class));
statusDetails
.stream()
.filter(deviceStatus -> deviceStatus.getName() != "Some Invalid Name")
.forEach(deviceStatus -> allDeviceStatuses
.put(deviceStatus.getName(), buildDevice(deviceStatus)));
return allDeviceStatuses;
}
/** More Stuff **/
}
and the Test :
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#Transactional
#Rollback
#ActiveProfiles("test")
public class SampleDatabaseServiceTest {
#SpyBean
#Qualifier("firstDbJdbcTemplate")
private JdbcTemplate firstDbJdbcTemplate;
#Autowired
private SampleDatabaseService serviceUnderTest;
#Before
public void populateTables() {
//Insert some Dummy Records in "InMemory HSQL DB" using firstDbJdbcTemplate
}
#Test
public void testReadAllValidDeviceStatus() {
// When
Map<String, Device> allDeviceStatuses = serviceUnderTest.readAllValidDeviceStatus();
// Then
assertThat(allDeviceStatuses).isNotNull().isNotEmpty();
// More checks
}
/* More Tests */
}
But, when i replace the #SpyBean with #Autowired in Test, it works fine.
Why is it so? Any help is greatly appreciated. :)
Use it in below format
#MockBean(name = "firstDbJdbcTemplate")
private JdbcTemplate firstDbJdbcTemplate;

Resources