Mocking an autowired object of base abstract class - spring

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.

Related

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);

java.lang.IllegalArgumentException: Could not find field 'isBoolean' of type [class java.lang.Boolean] on target object

When I run test then it failed at this point ReflectionTestUtils.setField(service, SeRepositoryImpl.class, "isBoolean",true,Boolean.class) complains about Could not find field 'isBoolean' of type not found. Error trace as below.
I am not sure why because my repositoryImpl class has isBoolean variable defined.
java.lang.IllegalArgumentException: Could not find field 'isBoolean' of type [class java.lang.Boolean] on target object [lautomation.repository.impl.SaRepositoryImpl#4a178d1e] or target class [lautomation.repository.impl.SaRepositoryImpl]
at org.springframework.test.util.ReflectionTestUtils.setField(ReflectionTestUtils.java:175)
test class looks like
#MockBean(name = "seRepository")
PolicyRepository seRepository;
#InjectMocks
private SeRepositoryImpl service;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testUpdateStatus() throws Exception{
ReflectionTestUtils.setField(service, SeRepositoryImpl.class, "isBoolean",true,Boolean.class);
List<Policy> policies = Arrays.asList(new Policy[] {new Policy() });
service.updateIssuedStatus(Mockito.any(Policy.class));
Mockito.verify(seRepository, Mockito.times(1)).updateIssuedStatus(Mockito.any(Policy.class));
}
}
Respository implementation class SeRepositoryImpl has isBoolean variable defined
#Repository("seRepository")
#Log4j
public class SeRepositoryImpl implements PolicyRepository {
#Value("${change-db}")
private boolean isBoolean;
#Autowired
#Qualifier("jdbcDbName")
private NamedParameterJdbcTemplate jdbcTemplate;
#Override
public void updateIssuedStatus(final Policy policy) {
if(!isBoolean) {
log.warn("isBoolean is set to false - skipping db write.");
return;
}
final HashMap<String, String> params = new HashMap<>();
params.put("issued",
new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
params.put("id", Integer.toString(policy.getId()));
jdbcTemplate.update(updateIssuedStatus, params);
String currDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
log.info("params:"+Integer.toString(policy.getId())+" Date:"+currDate);
final String sql = "call usp_updateDatabase(:policy,:currDate)";
MapSqlParameterSource value = new MapSqlParameterSource();
value.addValue("id",Integer.toString(policy.getId()));
value.addValue("stop_dt",new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
jdbcTemplate.update(sql, value);
}
}

NullPointerException by testing a Service with mocked JPARepository

I have a ServiceImp where the repository and objectmapper are injected.
When performing the tests I get a nullpointexception.
I believe the Mock is working because when I print the result Candidate createdOne = candidateRepository.save(c1) I get back c1.
#Service
#RequiredArgsConstructor(onConstructor = #__(#Autowired))
public class CandidateServiceImp implements CandidateService {
private final CandidateRepository candidateRepository;
private final ObjectMapper objectMapper;
#Override
public List<CandidateDto> getAllCandidates() {
List<Candidate> candidateList = candidateRepository.findAll();
return candidateList.stream()
.map(Candidate::convertEntityToDto)
.collect(Collectors.toList());
}
#Override
public String findCandidateByIdNormal(Long id) throws JsonProcessingException {
Candidate foundCandidate = candidateRepository.findById(id).orElseThrow(() -> new CandidateNotFoundException(id));
return objectMapper.writerWithView(CandidateViews.Normal.class).writeValueAsString(foundCandidate.convertEntityToDto());
}
#Override
public String findCandidateByIdHr(Long id) throws JsonProcessingException {
Candidate foundCandidate = candidateRepository.findById(id).orElseThrow(() -> new CandidateNotFoundException(id));
return objectMapper.writerWithView(CandidateViews.Hr.class).writeValueAsString(foundCandidate.convertEntityToDto());
}
#Override
public CandidateDto createCandidate(CandidateDto candidateToCreateDto) {
Candidate candidateToCreate = candidateToCreateDto.convertDtoToEntity();
Candidate createdCandidate = candidateRepository.save(candidateToCreate);
return createdCandidate.convertEntityToDto();
}
And this ist my test:
#ExtendWith(SpringExtension.class)
public class CandidateServiceTest {
#InjectMocks
CandidateServiceImp candidateServiceImp;
#Mock
CandidateRepository candidateRepository;
private CandidateDto c1Dto;
private CandidateDto c2Dto;
private List<CandidateDto> candidateDtoList;
private Candidate c1;
private Candidate c2;
private List<Candidate> candidateList;
#BeforeEach
void setUp() {
c1Dto = new CandidateDto("Peter", "Parker", "pp#gmail.com", 3500L);
c2Dto = new CandidateDto("Mary", "Jane", "mj#gmail.com", 4500L);
candidateDtoList = List.of(c1Dto, c2Dto);
c1 = new Candidate("Peter", "Parker", "pp#gmail.com", 3500L);
c2 = new Candidate("Mary", "Jane", "mj#gmail.com", 4500L);
candidateList = List.of(c1, c2);
}
#Test
public void createCandidateShouldReturnCandidateDto() {
Mockito.doReturn(c1).when(candidateRepository).save(c1);
Candidate createdOne = candidateRepository.save(c1);
System.out.println();
System.out.println(createdOne.convertEntityToDto());
System.out.println();
assertEquals(c1Dto, candidateServiceImp.createCandidate(c1Dto));
}
And this is the message :
java.lang.NullPointerException: Cannot invoke "de.evoila.personalAbteilung.models.Candidate.convertEntityToDto()" because "createdCandidate" is null
Could someone tell me why it is not finding the createdCandidate?Thanks =D
As explained in the comments, one solution would be to add #EqualsAndHashCode to candidate.
I also find other solution :
#Test
public void createCandidateShouldReturnCandidateDto() {
Mockito.when(candidateRepository.save(any(Candidate.class))).thenAnswer(AdditionalAnswers.returnsFirstArg());
assertEquals(c1Dto, candidateServiceImp.createCandidate(c1Dto));
}
I mocked the repository with any(Candidate.class) and it also works.

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?

How can I test the Hystrix-Fallback with JUnit MockMVC

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

Resources