How can I test the Hystrix-Fallback with JUnit MockMVC - spring

I need help with the jUnit testing, my result is json, and I need to test the Fallback method, that I bacome the RuntimeException that I build in the Update method in the Service. The test dont go to the fallback.
Controller.java
private static final Score defaultScore = new Score("Team1", "Team2", 1, 1);
#PutMapping(path = "")
#HystrixCommand(fallbackMethod = "updateScoreFallback")
public ResponseEntity<Score> updateScore(#RequestBody Score score) {
Score s = scoreService.updateScore(score);
return new ResponseEntity<>(s, headers, HttpStatus.OK);
}
public ResponseEntity<Score> updateScoreFallback(Score score) {
return new ResponseEntity<>(defaultScore, headers, HttpStatus.SERVICE_UNAVAILABLE);
}
My Test
#NoArgsConstructor
#RunWith(SpringRunner.class)
#WebMvcTest(value = ScoreController.class, secure = false)
public class ScoreControllerExceptionTests {
#Autowired
private MockMvc mockMvc;
#MockBean
private ScoreService ScoreService;
private ScoreController ScoreController;
private static final String basePath = "/v1/score";
private static final Score Score = new Score("Team1", "Team2", 1, 1);
private static final String mockScoreJson = "{\"id\":0,\"team_name1\":\"Team1\",\"team_name2\":\"Team2\",\"score_team1\":1,\"score_team2\":1}";
private static final List<Score> scoreList = Collections.singletonList(score);
private static final String mockScoreListJson = "[" + mockScoreJson + "]";
#Before
public void setUp() {
ScoreRepo scoreRepo = new ScoreRepoExceptionStub();
scoreService = new ScoreServiceImpl(scoreRepo);
scoreController = new ScoreController(scoreService);
mockMvc = MockMvcBuilders.standaloneSetup(scoreController).build();
}
#Test
public void updateScoreControllerException() throws Exception{
String result = mockMvc.perform(MockMvcRequestBuilders
.put(basePath)
.accept(MediaType.APPLICATION_JSON)
.content(mockScoreJson)
.contentType(MediaType.APPLICATION_JSON))
.andReturn()
.getResponse()
.getContentAsString();
Assert.assertEquals(mockScoreJson, result, true);
}
....
Thanks for the helps

Related

How can we mock Objects/REST Call when using FeignClient in Spring Boot (Microservices)?

I am working on Micro-Services Project and a requirement came where the communication between 2 micro-services need to happen. So, I used FeignClient Interface Approach to get it done.
Here is the FeignClientInterface.java Class:
#AuthorizedFeignClient(name = "fcfhpickorders")
public interface FCFHPickOrderService {
#PutMapping(value = "/api/prescriptions/prescriptionCode", consumes = {"application/json", "application/merge-patch+json"})
public ResponseEntity<PrescriptionDTO> updatePrescriptionForBucketKey(
#NotNull #RequestBody PrescriptionDTO prescriptionDTO
);
}
Below is the function where I used the above declared function:
public Bucket setLinkedPrescriptionCode(Bucket bucket) {
if (bucket.getLinkedPrescriptionCode() != null) {
PrescriptionDTO prescription = new PrescriptionDTO();
prescription.setBucketKey(bucket.getBucketKey());
prescription.setPrescriptionCode(bucket.getLinkedPrescriptionCode());
ResponseEntity<PrescriptionDTO> prescriptionDTOResponseEntity = fcfhPickOrderService.updatePrescriptionForBucketKey(prescription);
if(prescriptionDTOResponseEntity.getStatusCode().isError()) {
bucket.setLinkedPrescriptionCode(null);
bucketRepository.save(bucket);
throw new ResourceNotFoundException("Prescription with " + bucket.getLinkedPrescriptionCode() + "Not Found");
}
}
return bucket;
}
I used the setLinkedPrescriptionCode(Bucket bucket) function while saving and updating an existing bucket. It worked fine.
I have some previously written test cases for creation and updation of bucket that are failing now because of the addition of the REST call.
#IntegrationTest
#ExtendWith(MockitoExtension.class)
#AutoConfigureMockMvc
#WithMockUser
class BucketResourceIT {
private static final String DEFAULT_BUCKET_KEY = "AAAAAAAAAA";
private static final String UPDATED_BUCKET_KEY = "BBBBBBBBBB";
private static final String DEFAULT_QR_CODE = "AAAAAAAAAA";
private static final String UPDATED_QR_CODE = "BBBBBBBBBB";
private static final String DEFAULT_LINKED_PRESCRIPTION_CODE = "AAAAAAAAAA";
private static final String UPDATED_LINKED_PRESCRIPTION_CODE = "BBBBBBBBBB";
private static final String ENTITY_API_URL = "/api/buckets";
private static final String ENTITY_API_URL_ID = ENTITY_API_URL + "/{id}";
private static Random random = new Random();
private static AtomicLong count = new AtomicLong(random.nextInt() + (2 * Integer.MAX_VALUE));
#Autowired
private BucketRepository bucketRepository;
#Mock
private BucketRepository bucketRepositoryMock;
#Autowired
private BucketMapper bucketMapper;
#Mock
private BucketService bucketServiceMock;
#Autowired
private EntityManager em;
#Autowired
private MockMvc restBucketMockMvc;
private Bucket bucket;
#Mock
private FCFHPickOrderService fcfhPickOrderService;
public static Bucket createEntity(EntityManager em) {
Bucket bucket = new Bucket()
.bucketKey(DEFAULT_BUCKET_KEY)
.qrCode(DEFAULT_QR_CODE)
.linkedPrescriptionCode(DEFAULT_LINKED_PRESCRIPTION_CODE);
return bucket;
}
public static Bucket createUpdatedEntity(EntityManager em) {
Bucket bucket = new Bucket()
.bucketKey(UPDATED_BUCKET_KEY)
.qrCode(UPDATED_QR_CODE)
.linkedPrescriptionCode(UPDATED_LINKED_PRESCRIPTION_CODE);
return bucket;
}
#BeforeEach
public void initTest() {
bucket = createEntity(em);
}
#Test
#Transactional
void createBucket() throws Exception {
int databaseSizeBeforeCreate = bucketRepository.findAll().size();
// Create the Bucket
BucketDTO bucketDTO = bucketMapper.toDto(bucket);
restBucketMockMvc
.perform(
post(ENTITY_API_URL)
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(TestUtil.convertObjectToJsonBytes(bucketDTO))
)
*.andExpect(status().isCreated());*
// Validate the Bucket in the database
List<Bucket> bucketList = bucketRepository.findAll();
assertThat(bucketList).hasSize(databaseSizeBeforeCreate + 1);
Bucket testBucket = bucketList.get(bucketList.size() - 1);
assertThat(testBucket.getBucketKey()).isEqualTo(DEFAULT_BUCKET_KEY);
assertThat(testBucket.getQrCode()).isEqualTo(DEFAULT_QR_CODE);
assertThat(testBucket.getLinkedPrescriptionCode()).isEqualTo(DEFAULT_LINKED_PRESCRIPTION_CODE);
}
#Test
#Transactional
void putNewBucket() throws Exception {
bucketRepository.saveAndFlush(bucket);
int databaseSizeBeforeUpdate = bucketRepository.findAll().size();
// Update the bucket
Bucket updatedBucket = bucketRepository.findById(bucket.getId()).get();
// Disconnect from session so that the updates on updatedBucket are not directly saved in db
em.detach(updatedBucket);
updatedBucket.bucketKey(UPDATED_BUCKET_KEY).qrCode(UPDATED_QR_CODE).linkedPrescriptionCode(UPDATED_LINKED_PRESCRIPTION_CODE);
BucketDTO bucketDTO = bucketMapper.toDto(updatedBucket);
restBucketMockMvc
.perform(
put(ENTITY_API_URL_ID, bucketDTO.getId())
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(TestUtil.convertObjectToJsonBytes(bucketDTO))
)
*.andExpect(status().isOk());*
// Validate the Bucket in the database
List<Bucket> bucketList = bucketRepository.findAll();
assertThat(bucketList).hasSize(databaseSizeBeforeUpdate);
Bucket testBucket = bucketList.get(bucketList.size() - 1);
assertThat(testBucket.getBucketKey()).isEqualTo(UPDATED_BUCKET_KEY);
assertThat(testBucket.getQrCode()).isEqualTo(UPDATED_QR_CODE);
assertThat(testBucket.getLinkedPrescriptionCode()).isEqualTo(UPDATED_LINKED_PRESCRIPTION_CODE);
}
How should I update the above tests in order to fix the Assertion Errors that I am receiving?
BucketResourceIT > createBucket() FAILED
java.lang.AssertionError at BucketResourceIT.java:133
BucketResourceIT > putNewBucket() FAILED
java.lang.AssertionError at BucketResourceIT.java:294

How to test GET request with body in Spring RestController?

I have a rest controller like this;
#RestController
#RequiredArgsConstructor
#RequestMapping(PO)
public class PoController {
private final PoService service;
#GetMapping(value = FILTER, produces = APPLICATION_JSON_VALUE)
public ResponseEntity<List<PoDTO>> filter(PoFilterCriteria poFilterCriteria) {
return ok().body(service.getPos(poFilterCriteria));
}
}
And I want to write an unit test for it but I couldn't achieve to mock the service to return list.
This is my poFilterCriteria model;
#Data
public class PoFilterCriteria {
private double hp;
private FilterOperationType hpOperationType;
private double attack;
private FilterOperationType attackOperationType;
private double defense;
private FilterOperationType defenseOperationType;
}
And this is my test;
#WebMvcTest(value = PoController.class)
class PoControllerTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private PoService service;
private PoDTO poDTO;
private List<PoDTO> poDTOList;
#BeforeEach
void setUp() {
poDTOList = new ArrayList<>();
poDTO = new Po();
poDTOList.add(poDTO);
}
#Test
public void filter_success() throws Exception {
PoFilterCriteria poFilterCriteria= new PoFilterCriteria ();
poFilterCriteria.setAttack(40);
poFilterCriteria.setAttackOperationType(GT);
poFilterCriteria.setHp(49);
poFilterCriteria.setHpOperationType(EQ);
poFilterCriteria.setDefense(60);
poFilterCriteria.setDefenseOperationType(LT);
when(service.getPos(poFilterCriteria)).thenReturn(poDTOList);
mockMvc.perform(get(PO + FILTER)
.param("hp", String.valueOf(40))
.param("hpOperationType", String.valueOf(GT))
.param("attack", String.valueOf(49))
.param("attackOperationType", String.valueOf(EQ))
.param("defense", String.valueOf(60))
.param("defenseOperationType", String.valueOf(LT))
.contentType(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().json(new ObjectMapper().writeValueAsString(poDTOList)));
}
}
But the list that should return with size of 1 is returning empty.
What did I do wrong?
org.mockito.ArgumentMatchers#any(java.lang.Class)
when(service.getPos(any(PoFilterCriteria.class))).thenReturn(poDTOList);
or
org.mockito.ArgumentMatchers#same
when(service.getPos(same(poFilterCriteria))).thenReturn(poDTOList);

Spring Controller Test: Postman vs JUnit - Field error request rejected value [null]

I'm a beginner on Spring framework, trying to test the Controller.
The funny thing is, using Postman, I got the correct response, but not in JUnit where receive Actual :400 (bad request) instead of Expected :200.
This is due to empty field passengerCount because appears null. The class of the request is different of the response. This latter doesn't have a field for the passenger.
Controller
#Validated
#RestController
#RequestMapping("flights")
public class BusyFlightsController {
CrazyAirDatabase crazyAirService;
#Autowired
public BusyFlightsController(CrazyAirDatabase crazyAirService) {
this.crazyAirService = new CrazyAirDatabase();
}
#RequestMapping(value = "/crazy-air-response", method = RequestMethod.GET, produces = "application/json")
public List<CrazyAirResponse> getCrazyAirResponse(
#Valid CrazyAirRequest crazyAirRequest,
#RequestParam("origin") String origin,
#RequestParam("destination") String destination,
#RequestParam("departureDate") String departureDate,
#RequestParam("returnDate") String returnDate,
#RequestParam("passengerCount") int passengerCount
) {
crazyAirRequest = new CrazyAirRequest(origin, destination, departureDate, returnDate,
passengerCount);
return crazyAirService.getCrazyAirResponse(crazyAirRequest);
}
}
CrazyAirRequest class
public class CrazyAirRequest {
#IATACodeConstraint
private String origin;
#IATACodeConstraint
private String destination;
private String departureDate;
private String returnDate;
private int passengerCount;
public CrazyAirRequest(String origin, String destination, String departureDate,
String returnDate, int passengerCount) {
this.origin = origin;
this.destination = destination;
this.departureDate = departureDate;
this.returnDate = returnDate;
this.passengerCount = passengerCount;
}
// Getters
}
CrazyAirResponse class
public class CrazyAirResponse {
private String airline;
private double price;
private String cabinClass;
private String departureAirportCode;
private String destinationAirportCode;
private String departureDate;
private String arrivalDate;
public CrazyAirResponse(String airline, double price, String cabinClass, String departureAirportCode,
String destinationAirportCode, String departureDate, String arrivalDate) {
this.airline = airline;
this.price = price;
this.cabinClass = cabinClass;
this.departureAirportCode = departureAirportCode;
this.destinationAirportCode = destinationAirportCode;
this.departureDate = departureDate;
this.arrivalDate = arrivalDate;
}
// Getters
}
Repo CrazyAirDatabase
#Component
public class CrazyAirDatabase implements CrazyAirService {
List<CrazyAirResponse> list;
public CrazyAirDatabase() {
list = new ArrayList<>(
Arrays.asList(
new CrazyAirResponse("Ryanair", 125, "E", "LHR",
"BRN", "2018-10-08", "2020-10-08")
);
}
#Override
public List<CrazyAirResponse> getCrazyAirResponse(CrazyAirRequest request) {
return list.stream()
.filter(t -> t.getDepartureAirportCode().equals(request.getOrigin()) &&
t.getDestinationAirportCode().equals(request.getDestination()) &&
t.getDepartureDate().equals(request.getDepartureDate()) &&
t.getArrivalDate().equals(request.getReturnDate())
)
.collect(Collectors.toList());
}
}
Test
#RunWith(SpringRunner.class)
#SpringBootTest
#AutoConfigureMockMvc
public class BusyFlightsControllerTest {
#Autowired
MockMvc mockMvc;
#Mock
CrazyAirRequest crazyAirRequest;
#InjectMocks
private BusyFlightsController controller;
#Mock
CrazyAirService service;
#Before
public void before() {
MockitoAnnotations.initMocks(this);
this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
#Test
public void testino() throws Exception {
crazyAirRequest = new CrazyAirRequest("LHR",
"BRN", "2018-10-08", "2020-10-08", 120);
List<CrazyAirResponse> crazyAirResponse = Arrays.asList(new CrazyAirResponse("Ryanair", 125,
"E", "LHR",
"BRN", "2018-10-08", "2020-10-08")
);
when(service.getCrazyAirResponse(crazyAirRequest)).thenReturn(crazyAirResponse);
ObjectMapper objectMapper = new ObjectMapper();
String airplane = objectMapper.writeValueAsString(crazyAirResponse);
ResultActions result = mockMvc.perform(get("/flights/crazy-air-response")
.contentType(MediaType.APPLICATION_JSON)
.content(airplane)
);
result.andExpect(status().isOk());
}
}
If I put this:
ResultActions result = mockMvc.perform(get("/flights/crazy-air-response?origin=LHR&destination=CTA&departureDate=some&returnDate=some&passengerCount=1")
.contentType(MediaType.APPLICATION_JSON)
.content(airplane)
);
Test is passed.
Then, need I perform Postman first, and after to copy and paste the query to pass the test?

Mocking an autowired object of base abstract class

I'm writing the Junit test case for a class which is extended by an abstract class. This base abstract class has an autowired object of a different class which is being used in the class I'm testing.
I'm trying to mock in the subclass, but the mocked object is throwing a NullPointerException.
Example:
// class I am testing
public class GetTransactionsForProcessorGroupActivity extends GetTransactionsBaseActivity {
private static final Logger log = LogManager.getLogger(GetTransactionsForProcessorGroupActivity.class);
public GetTransactionsForProcessorGroupActivity(ARHFactory arhFactory, MetricsFactory metricsFactory) {
super(arhFactory, metricsFactory);
}
#Override
protected List<OverseasTransaction> getOverseasTransactions(Document herdDocument)
throws IllegalDateFormatException, ProcessorConfigurationException, DocumentException {
final String paymentProcessorGroup = HerdDocumentUtils.getPaymentProcessor(herdDocument);
final Date runDate = HerdDocumentUtils.getRunDate(herdDocument);
final List<String> paymentProcessorList = ProcessorGroupLookup.getProcessorsFromGroup(paymentProcessorGroup);
List<OverseasTransaction> overseasTransactionList = new ArrayList<OverseasTransaction>();
List<ProcessorTransactionWindow> processingWindows = new ArrayList<ProcessorTransactionWindow>();
for (final String processor : paymentProcessorList) {
ProcessorTransactionWindow transactionWindow = ProcessorCalendarUtils.getProcessorTransactionWindow(processor, runDate);
processingWindows.add(transactionWindow);
final Date processingFromDate = transactionWindow.getFromDate();
final Date processingToDate = transactionWindow.getToDate();
//NullpointerException on this line, as OverseasTransactionStore mock object returns null.
final List<OverseasTransaction> transactions = overseasTransactionsStore
.queryOverseasTransactionsOnPPTimelineandDates(processor, processingFromDate, processingToDate);
overseasTransactionList.addAll(transactions);
}
HerdDocumentUtils.putProcessingWindowDetails(herdDocument, processingWindows);
return overseasTransactionList;
}
}
// Base class
public abstract class GetTransactionsBaseActivity extends CoralHerdActivity implements ActionRequestHandler {
private static final Logger log = LogManager.getLogger(GetTransactionsBaseActivity.class);
#SuppressWarnings("unchecked")
private static final Map<String, String> S3_CONFIGURATION = AppConfig.findMap(Constants.S3_CONFIGURATION_KEY);
private static final String S3_BUCKET = S3_CONFIGURATION.get(Constants.BUCKET_NAME);
private static final class Status {
private static final String PROCESSOR_DETAILS_NOT_FOUND = "NoPaymentProcessorDetailsPresent";
private static final String TRANSACTIONS_OBTAINED = "TransactionsObtained";
private static final String NO_TRANSACTIONS_TO_BE_CONSIDERED = "NoTransactionsToBeConsidered";
private static final String NEGATIVE_OR_ZERO_AMOUNT = "NegativeOrZeroAmount";
}
protected final ARHFactory arhFactory;
protected final MetricsFactory metricsFactory;
#Autowired
OverseasTransactionsStore overseasTransactionsStore;
#Autowired
S3ClientProvider s3ClientProvider;
protected abstract List<OverseasTransaction> getOverseasTransactions(Document herdDocument)
throws IllegalDateFormatException, ProcessorConfigurationException, DocumentException;
#Override
public ActionResponse postActionRequest(final ActionRequest request) throws Exception {
TimedARH timedARH = (TimedARH) arhFactory.createARH();
timedARH.setHandler(this);
return timedARH.handle(request);
}
public ActionResponse handle(final ActionRequest request) throws Exception {
final Document herdDocument = HerdDocumentUtils.getFundFlowDocument(request);
final Metrics metrics = MetricsLogger.getMetrics(metricsFactory);
final String paymentProcessor = HerdDocumentUtils.getPaymentProcessor(herdDocument);
try {
final List<OverseasTransaction> overseasTransactionList;
MetricsLogger.logFundFlowExecution(metrics, paymentProcessor);
try {
overseasTransactionList = getOverseasTransactions(herdDocument);
} catch (ProcessorConfigurationException e) {
return new ActionComplete(Status.PROCESSOR_DETAILS_NOT_FOUND, herdDocument);
}
if (CollectionUtils.isEmpty(overseasTransactionList)) {
MetricsLogger.logTransactionMetrics(metrics, paymentProcessor, 0, BigDecimal.ZERO);
return new ActionComplete(Status.NO_TRANSACTIONS_TO_BE_CONSIDERED, herdDocument);
}
final String s3ObjectKey = getS3ObjectKey(request, paymentProcessor);
storeTransactionsInS3(overseasTransactionList, S3_BUCKET, s3ObjectKey);
final int itemCount = overseasTransactionList.size();
BigDecimal totalAmount = BigDecimal.ZERO;
for (OverseasTransaction overseasTransaction : overseasTransactionList) {
if (StringUtils.equalsIgnoreCase(overseasTransaction.getType(), Constants.TRANSACTION_TYPE_CHARGE)) {
totalAmount = totalAmount.add(overseasTransaction.getOverseasAmount());
} else if (StringUtils.equalsIgnoreCase(overseasTransaction.getType(), Constants.TRANSACTION_TYPE_REFUND)) {
totalAmount = totalAmount.subtract(overseasTransaction.getOverseasAmount());
}
}
MetricsLogger.logTransactionMetrics(metrics, paymentProcessor, itemCount, totalAmount);
HerdDocumentUtils.putS3Location(herdDocument, S3_BUCKET, s3ObjectKey);
HerdDocumentUtils.putTotalAmount(herdDocument, totalAmount);
HerdDocumentUtils.putTransactionItemCount(herdDocument, itemCount);
HerdDocumentUtils.putPaymentProcessor(herdDocument, paymentProcessor);
if (totalAmount.compareTo(BigDecimal.ZERO) <= 0) {
log.info("Total amount to disburse is zero or negative. {}", totalAmount);
return new ActionComplete(Status.NEGATIVE_OR_ZERO_AMOUNT, herdDocument);
}
return new ActionComplete(Status.TRANSACTIONS_OBTAINED, herdDocument);
} finally {
MetricsLogger.closeMetrics(metrics);
}
}
}
// Test class
#RunWith(PowerMockRunner.class)
#PowerMockIgnore({ "javax.management.*" })
#PrepareForTest({ HerdDocumentUtils.class, ProcessorGroupLookup.class })
public class GetTransactionsForProcessorGroupActivityTest extends AppConfigInitializedTestBase {
private static HerdInput herdInput;
private static HerdOutput herdOutput;
private static final String paymentProcessorGroup = "BillDesk";
private static final String paymentProcessorGroupNotFound = "IndiaPaymentGateway";
#Mock
ActionRequest request;
#Mock
WorkItemIdentifier workItemId;
#Mock
private CoralHerdActivity coralHerdActivity;
#Mock
Metrics metrics;
#Mock
Map<String, String> S3_CONFIGURATION_MAP;
#Mock
MetricsFactory metricsFactory;
#Mock
ARHFactory arhFactory;
#Mock
Document herdDocument;
#Mock
OverseasTransactionsStore overseasTransactionsStore;
#Mock
S3ClientProvider s3ClientProvider;
// #InjectMocks
// GetTransactionsForProcessorGroupActivity getTransactionsBaseActivityTest;
// new GetTransactionsForProcessorGroupActivity(arhFactory, metricsFactory);
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
PowerMockito.mockStatic(HerdDocumentUtils.class);
// PowerMockito.mockStatic(ProcessorGroupLookup.class);
// GetTransactionsBaseActivity getTransactionsBaseActivity = new GetTransactionsBaseActivity(overseasTransactionsStore);
}
#Test
public void testEnact() {
GetTransactionsForProcessorGroupActivity getTransactionsForProcessorGroupActivity = Mockito
.mock(GetTransactionsForProcessorGroupActivity.class, Mockito.CALLS_REAL_METHODS);
Mockito.when(coralHerdActivity.enact(herdInput)).thenReturn(herdOutput);
final HerdOutput actualHerdOutput = getTransactionsForProcessorGroupActivity.enact(herdInput);
Assert.assertNotNull(actualHerdOutput);
}
#Test
public void testgetpaymentProcessorList() throws Exception {
Date date = new Date();
List<String> paymentProcessorList;
PowerMockito.when(HerdDocumentUtils.getPaymentProcessor(herdDocument)).thenReturn(paymentProcessorGroup);
PowerMockito.when(HerdDocumentUtils.getRunDate(herdDocument)).thenReturn(date);
paymentProcessorList = ProcessorGroupLookup.getProcessorsFromGroup(paymentProcessorGroup);
assertNotNull(paymentProcessorList);
}
#Test(expected = ProcessorConfigurationException.class)
public void testpaymentProcessorListNotFound() {
Date date = new Date();
PowerMockito.when(HerdDocumentUtils.getPaymentProcessor(herdDocument))
.thenReturn(paymentProcessorGroupNotFound);
PowerMockito.when(HerdDocumentUtils.getRunDate(herdDocument)).thenReturn(date);
List<String> paymentProcessorList = ProcessorGroupLookup.getProcessorsFromGroup(paymentProcessorGroupNotFound);
assertNotNull(paymentProcessorList);
}
#Test
public void canGetOverseasTransactiontest() throws Exception {
GetTransactionsForProcessorGroupActivity getTransactionsForProcessorGroupActivity = Mockito
.mock(GetTransactionsForProcessorGroupActivity.class);
// OverseasTransactionsStore overseasTransactionsStore =
// Mockito.mock(OverseasTransactionsStoreImpl.class);
Date date = new Date();
MockitoAnnotations.initMocks(this);
PowerMockito.when(HerdDocumentUtils.getPaymentProcessor(herdDocument)).thenReturn(paymentProcessorGroup);
PowerMockito.when(HerdDocumentUtils.getRunDate(herdDocument)).thenReturn(date);
// List<String> paymentProcessorList = new ArrayList<>();
// paymentProcessorList.add("BillDesk");
// PowerMockito.when(ProcessorGroupLookup.getProcessorsFromGroup(paymentProcessorGroup))
// .thenReturn(paymentProcessorList);
String fromDate = "Sat Mar 16 23:59:59 IST 2019";
String toDate = "Sat Mar 16 23:59:59 IST 2019";
DateFormat dateFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
List<OverseasTransaction> overseasTransactionList1 = createMockOverseasTransaction();
Mockito.doReturn(overseasTransactionList1).when(overseasTransactionsStore)
.queryOverseasTransactionsOnPPTimelineandDates(Mockito.isA(String.class), Mockito.isA(Date.class),
Mockito.isA(Date.class));
Mockito.when(getTransactionsForProcessorGroupActivity.getOverseasTransactions(herdDocument))
.thenCallRealMethod();
List<OverseasTransaction> overseasTransactionList = getTransactionsForProcessorGroupActivity
.getOverseasTransactions(herdDocument);
assertNotNull(overseasTransactionList);
// assertEquals(overseasTransactionList.getPaymentProcessorID(), actual);
}
private List<OverseasTransaction> createMockOverseasTransaction() {
Date date = new Date();
BigDecimal num = new BigDecimal(100001);
List<OverseasTransaction> overseasTransactionList = new ArrayList<OverseasTransaction>();
OverseasTransaction overseasTransaction = new OverseasTransaction();
overseasTransaction.setPurchaseID("purchaseID");
overseasTransaction.setSignatureID("signatureID");
overseasTransaction.setPaymentProcessorTransactionID("paymentProcessorTransactionID");
overseasTransaction.setType("Charge");
overseasTransaction.setSubType("subType");
overseasTransaction.setTransactionTimestamp(date);
overseasTransaction.setPaymentMethod("paymentMethod");
overseasTransaction.setTotalAmount(num);
overseasTransaction.setOverseasAmount(num);
overseasTransaction.setCurrency("currency");
overseasTransaction.setMarketplaceID("marketplaceID");
overseasTransaction.setOrderMetadata("orderMetadata");
overseasTransaction.setDisbursementID("disbursementID");
overseasTransaction.setReconState(1);
overseasTransaction.setPaymentProcessorID("BillDesk");
overseasTransaction.setRemittanceFileStatus("remittanceFileStatus");
overseasTransaction.setCrowID("crowID");
overseasTransaction.setSource("source");
overseasTransactionList.add(overseasTransaction);
return overseasTransactionList;
}
}
In my test file when I mock OverseasTransaction object, it gives me a NullPointerException. Do you have any suggestions about how we can mock this? All the above commented lines in my test indicates the things I tried but they still seem to throw the same error.
StackTrace of error: while executing canGetOverseasTransactiontest
N/A
java.lang.NullPointerException
at com.ingsfundflowservice.activity.GetTransactionsForProcessorGroupActivity.getOverseasTransactions(GetTransactionsForProcessorGroupActivity.java:71)
at com.ingsfundflowservice.activity.GetTransactionsForProcessorGroupActivityTest.canGetOverseasTransactiontest(GetTransactionsForProcessorGroupActivityTest.java:172)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120)
at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53)
at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59)
You need to create object of Class which for which you are writing the test. i.e. GetTransactionsForProcessorGroupActivity. There is what you can do
#RunWith(MockitoJUnitRunner.class)
public class GetTransactionsForProcessorGroupActivityTest {
#InjectMocks
private GetTransactionsForProcessorGroupActivity getTransactionsForProcessorGroupActivity;
#Mock
private OverseasTransaction overseastransaction;
#Test
public void test() {
Mockito.when(overseastransaction.somemethod()).thenReturn(something);
}
}
This will make sure that getTransactionsForProcessorGroupActivity is created and overseastransaction is injected with mock object.
Please note the class annotation #RunWith. This make sure that all the properties are injected with mock object properly. Also, you can use Mockito instead of PowerMockito.
You can add a protected setter in the abstract class and then in your GetTransactionsForProcessorGroupActivity you can call the setter in the constructor.
Then you just use #Mock the field you need to set and then you either use #InjectMocks or more suggested to call the constructor in the #Setup method including the mock field to be set.

how to use mockito and junit to test my spring boot rest api?

I'm new in unit testing and cannot figure out how to test the RESTFul API with Spring using Mockito and Junit, first of all i have preapared the class in which i created two method with #Before and #Test, when i turned in debugging mode it tells me that hasSize collection return 0 not 4.
#RunWith(SpringJUnit4ClassRunner.class)
public class EmployeControllerTest {
private MockMvc mockMvc;
#InjectMocks
private EmployeController employeController ;
#Mock
private EmployeService employeService ;
#Before
public void setUp() throws Exception{
MockitoAnnotations.initMocks(this);
mockMvc=MockMvcBuilders.standaloneSetup(employeController).build();
}
#Test
public void testgetAllEmployee() throws Exception{
List<Employe> employes= Arrays.asList(
new Employe("Hamza", "Khadhri", "hamza1007", "123")
,new Employe("Oussema", "smi", "oussama", "1234") );
when(employeService.findAll()).thenReturn(employes);
mockMvc.perform(get("/employe/dto"))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$", hasSize(4)))
.andExpect(jsonPath("$[0].nom", is("Hamza")))
.andExpect(jsonPath("$[0].prenom", is("Khadhri")))
.andExpect(jsonPath("$[0].login", is("hamza1007")))
.andExpect(jsonPath("$[0].mp", is("123")))
.andExpect(jsonPath("$[1].nom", is("Oussema")))
.andExpect(jsonPath("$[1].prenom", is("smi")))
.andExpect(jsonPath("$[1].login", is("oussama")))
.andExpect(jsonPath("$[1].mp", is("1234")));
verify(employeService,times(1)).findAll();
verifyNoMoreInteractions(employeService);
}
}
here is the EmployeController :
#CrossOrigin(origins = "*", allowedHeaders = "*")
#RestController
#RequestMapping("/employe")
public class EmployeController {
#Autowired
private EmployeService employeService;
#Autowired
private ModelMapper modelMapper;
#GetMapping("/dto")
public List<EmployeDTO> getEmployeDTOList(){
try {
List<Employe> listemp=employeService.findAllEmployeActive();
return listemp.stream()
.map(emp ->convertToDto(emp))
.collect(Collectors.toList());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private EmployeDTO convertToDto(Employe emp) {
EmployeDTO empDto = modelMapper.map(emp, EmployeDTO.class);
return empDto;
}
}
when I turn in debugging mode, it tells me that there is NullPointerException.
How to use properly mockito and junit to succeed the test?
I see a few potential issues:
First, you are calling
List<Employe> listemp=employeService.findAllEmployeActive();
in your controller's getEmployeDTOList(), but your Mockito mock is written as:
when(employeService.findAll()).thenReturn(employes)
So, your test might not be working simply because your mock never happens.
Second, you have not mocked the ModelMapper that you autowired in your controller. I think Spring will still go ahead and grab that component for you (someone correct me if I'm wrong there), but either way it's not great practice to have your unit tests be dependent on external libraries since you should only be concerned with the controller's functionality. It would be better to mock ModelMapper to make it "always" work and write separate tests to validate your mappings.
I went ahead and made my own version of your code to test things out. I changed hasSize to 2 because you were only using two elements in your example.
This test is working for me:
#RunWith(SpringJUnit4ClassRunner.class)
public class EmployeeControllerTest {
private MockMvc mockMvc;
#InjectMocks
private EmployeeController employeeController ;
#Mock
private EmployeeService employeeService;
#Mock
private ModelMapper modelMapper;
#Before
public void setUp() throws Exception{
MockitoAnnotations.initMocks(this);
mockMvc=MockMvcBuilders.standaloneSetup(employeeController).build();
}
#Test
public void testgetAllEmployeeWithModelMapper() throws Exception{
Employee emp1 = new Employee("Hamza", "Khadhri", "hamza1007", "123");
Employee emp2 = new Employee("Oussema", "smi", "oussama", "1234");
List<Employee> Employees= Arrays.asList(emp1, emp2);
EmployeeDTO dto1 = new EmployeeDTO("Hamza", "Khadhri", "hamza1007", "123");
EmployeeDTO dto2 = new EmployeeDTO("Oussema", "smi", "oussama", "1234");
when(modelMapper.map(emp1,EmployeeDTO.class)).thenReturn(dto1);
when(modelMapper.map(emp2,EmployeeDTO.class)).thenReturn(dto2);
when(employeeService.findAll()).thenReturn(Employees);
mockMvc.perform(get("/employe/dto"))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].nom", is("Hamza")))
.andExpect(jsonPath("$[0].prenom", is("Khadhri")))
.andExpect(jsonPath("$[0].login", is("hamza1007")))
.andExpect(jsonPath("$[0].mp", is("123")))
.andExpect(jsonPath("$[1].nom", is("Oussema")))
.andExpect(jsonPath("$[1].prenom", is("smi")))
.andExpect(jsonPath("$[1].login", is("oussama")))
.andExpect(jsonPath("$[1].mp", is("1234")));
verify(employeeService,times(1)).findAll();
verifyNoMoreInteractions(employeeService);
}
}
As you can see I create my own DTO objects and pass them back so that modelMapper will always behave as expected for this unit test.
This is the code that works but it ignores the object emp1:
public void testgetAllEmployeeWithModelMapper() throws Exception{
Employe emp1 = new Employe("Hamza", "Khadhri", "hamza1007", "123");
Employe emp2 = new Employe("Oussem", "smi", "oussama", "1234");
List<Employe> Employees= Arrays.asList(emp1, emp2);
EmployeDTO dto1 = new EmployeDTO("Hamza", "Khadhri", "hamza1007", "123");
EmployeDTO dto2 = new EmployeDTO("Oussem", "smi", "oussama", "1234");
when(modelMapper.map(emp1,EmployeDTO.class)).thenReturn(dto1);
when(modelMapper.map(emp2,EmployeDTO.class)).thenReturn(dto2);
when(employeeService.findAll()).thenReturn(Employees);
mockMvc.perform(get("/employe/dto"))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
.andExpect(jsonPath("$", hasSize(2)))
.andExpect(jsonPath("$[0].nom", is("Hamza")))
.andExpect(jsonPath("$[0].prenom", is("Khadhri")))
.andExpect(jsonPath("$[0].login", is("Hamza1007")))
.andExpect(jsonPath("$[0].mp", is("123")))
.andExpect(jsonPath("$[1].nom", is("Oussema")))
.andExpect(jsonPath("$[1].prenom", is("smi")))
.andExpect(jsonPath("$[1].login", is("oussama")))
.andExpect(jsonPath("$[1].mp", is("1234")));
verify(employeeService,times(1)).findAll();
verifyNoMoreInteractions(employeeService);
}
}
The cosole shows me that jsonPath("$[0].nom" expect Oussema
so when i change it to Oussema which is the object emp2 and it works well. unfortunately it ignores the the object emp1 which contain Hamza,
personnaly i just add two constructor in Employe and EmployeDTO.
this is the class Employe:
public class Employe implements Serializable {
#Id
#Column(unique=true, nullable=false, precision=6)
private Long id;
#Column(precision=6)
private BigDecimal cv;
#Column(length=254)
private String nom;
#Column(length=254)
private String prenom;
#Column(length=254)
private String login;
#Column(length=254)
private String mp;
#Column(length=254)
private String mail;
#Column(precision=6)
private BigDecimal idpointage;
#Column(length=1)
private Boolean actif;
public Employe(String nom, String prenom, String login, String mp) {
this.nom = nom;
this.prenom = prenom;
this.login = login;
this.mp = mp;
}
this is the class EmployeDTO:
public class EmployeDTO {
private String nom;
private String prenom;
private String login ;
private String mp ;
public EmployeDTO(String nom, String prenom, String login, String mp) {
this.nom= nom ;
this.prenom= prenom ;
this.login = login ;
this.mp=mp ;
}

Resources