How to mock DynamoDB batch save? - java

I wrote the dynamoDB code which stores list of items.
mapper.batchSave(trafficSensorReadings)
This will return.
List<FailedBatch>
I want to mock the mapper.batchSave and then return one failed job. How can I achieve it? I am using mockito and Junit.
I wrote something like this. But not useful.
when(dynamoDBMapper.batchSave(eq(List.class))).thenReturn(mock(List.class));

A complete example follows
#Test
public void test() {
FailedBatch failedBatch = mock(FailedBatch.class);
List<FailedBatch> failedBatchList = new ArrayList<>();
failedBatchList.add(failedBatch);
DynamoDBMapper dynamoDBMapperMock = mock(DynamoDBMapper.class);
when(dynamoDBMapperMock.batchSave(any(List.class))).thenReturn(failedBatchList);
tested.testedMethodCall();
verify(dynamoDBMapperMock).batchSave(any(List.class));
}

First, I think you might want to use Mockito.any() instead of Mockito.eq().
Second, I don't see why you would want to mock the list. You can just create one and return it
// GIVEN
FailedBatch batch1 = /**/;
FailedBatch batch2 = /**/;
List<FailedBatch> failedBatchList = Lists.newArrayList(batch1, batch2);
// WHEN
when(dynamoDBMapper.batchSave(any(List.class))).thenReturn(failedBatchList);
Object someResult = yourFunctionTestCall();
// THEN
verify(someResult)...

Related

How do I write a Mockito test case?

Hi I was writing a test case for
#Override
public SnapDocument updateFlights(SnapDocument snapDocument, FlightListingResponse flightsResponse) {
HashMap<String, FaresInfo> outboundFlights = new HashMap<>();
HashMap<String, FaresInfo> inboundFlights = new HashMap<>();
Objects.requireNonNull(flightsResponse.getOutboundFlights()).getFlights().forEach(faresInfo -> outboundFlights.put(faresInfo.getJourneySellKey(), faresInfo));
Objects.requireNonNull(flightsResponse.getReturnFlights()).getFlights().forEach(faresInfo -> inboundFlights.put(faresInfo.getJourneySellKey(), faresInfo));
snapDocument.setOutboundFlights(outboundFlights);
snapDocument.setInboundFlights(inboundFlights);
return snapDocument;
}
This is the test case I have written
public void updateFilghtsSuccess(){
when(snapService.getSnapDocument(any())).thenReturn(snapDocument);
when(snapService.updateFlights(snapDocument, flightListingResponse)).thenReturn(snapDocument);
verify(snapService).updateFlights(snapDocument, flightListingResponse);
}
The build is failing, How to write the test cases for this so that I can improve the coverage of my code?
when, given and verify should only be used when dealing with mocks.
As your code works with plain old java objects and no other external components are called, you do not need them.
Just construct the pojos to pass to the method and assert that the pojo that comes back out contains the correct values. You don't need mockito for that, as the test does not require mocks.
#Test
void testUpdateFlights() {
// Arrange
SnapService snapService = new SnapServiceImpl();
SnapDocument sd = new SnapDocument();
FlightListingResponse response = new FlightListingResponse();
response.setOutboundFlights(...);
response.setReturnFlights(...);
// Act
SnapDocument result = snapService.updateFlights(sd, response);
// Assert
assertThat(result.getOutboundFlights()).contains(...);
}
You do not need them now, but when would you need a mock? If your code calls a component that is not under test and you don't want that the actual implementation of it is executed. Unit tests are to test 1 unit of work. All other external components should be mocked out.

Testing a method which calls another method

I have a method in my service layer:
public List<String> sortBarcodesByTotalPrice(Set<String> barcodesByBookType) {
List<String> toSort = new ArrayList<>();
for (String barcode : barcodesByBookType) {
[1] String combined = barcode + "/" + priceOperations.calculatePriceByBarcode(barcode);
toSort.add(combined);
}
[2] toSort.sort(new TotalPriceComparator());
return toSort;
}
[1] this line gets barcode, lets say "ABC" and then calls a method in another class which retrieves information from the database about that item, performs calculation and returns the price.
The possible combined value could be something like "ABC/10".
[2] sorts all the values by price, ascending. So if List contains and "DEF/15" and "ABC/10" it gets sorted to [0] = "ABC/10", [1]= "DEF/15".
When I try to test this method, I get null pointer exception when priceOperations.calculatePRiceByBarcode(barode) gets called. How do I test this method? I've tried searching and found some questions and answers about using mockito but I can't figure out how to implement this.
my current attempt at testing this method:
#Test
void sortBarcodesByTotalPrice() {
Set<String> toSort = new HashSet<>();
toSort.add("ABC/10");
toSort.add("DEF/5");
toSort.add("GHI/15");
List<String> sorted = bookService.sortBarcodesByTotalPrice(toSort);
assertEquals(sorted.get(0), "GHI");
assertEquals(sorted.get(1), "ABC");
assertEquals(sorted.get(2), "DEF");
}
EDIT, SOLUTION:
I have figured out how to solve this thanks to information from Kaj Hejer. This is my new test method, passing and working as intended, if I understand this correctly:
#Test
void sortBarcodesByTotalPrice() {
PriceOperations priceOperations = Mockito.mock(PriceOperations.class);
Set<String> toSort = new HashSet<>();
toSort.add("GHI");
toSort.add("ABC");
toSort.add("DEF");
when(priceOperations.calculatePriceByBarcode("GHI")).thenReturn(new BigDecimal("15"));
when(priceOperations.calculatePriceByBarcode("ABC")).thenReturn(new BigDecimal("10"));
when(priceOperations.calculatePriceByBarcode("DEF")).thenReturn(new BigDecimal("5"));
BookService bookService = new BookService(null, null, priceOperations);
List<String> sorted = bookService.sortBarcodesByTotalPrice(toSort);
assertEquals(sorted.get(0), "DEF/5");
assertEquals(sorted.get(1), "ABC/10");
assertEquals(sorted.get(2), "GHI/15");
}
First you have to decide what to test where. You might want to have separate tests for BookService and for the PriceOperations class. Now your test are tesing both these classes.
If you want to write a test for the BookService class you can mock the PriceOperations class.
List<String> sorted = new ArrayList<>();
sorted.add("GHI");
sorted.add("ABC");
sorted.add("DEF");
PriceOperations priceOperations = Mockito.mock(PriceOperations.class);
when(priceOperations. calculatePriceByBarcode(Mockito.<String>anyList())).thenReturn(sorted);
When injecting the PriceOperations into the BookService constructor injection is a smart way of injecting because it make it easier to write tests. Then you can inject the mocked priceOperations with
BookService bookService = new BookService(priceOperations);
Please let me know if this is useful!

How to return a list of results in jOOQ Mocked Data

I'm using jOOQ's MockDataProvider to mock calls to the database. I've figured out how to return a single record using the information here: https://blog.jooq.org/2013/02/20/easy-mocking-of-your-database/
However, I want to return a list of results not just a single record for my query. How do I do that?
I can use the following (from the above link) to return a single result:
return new MockResult[] {
new MockResult(1, result)
};
However, I cannot figure out how to add multiple results, all of the constructors for MockResult only take a single result. Any hints? Am I missing something obvious?
For example if I query all bicycles that are road bikes:
SELECT * FROM bicycles WHERE type = "road";
how do I return a list of 10 bicycles instead of just one?
I can use the following (from the above link) to return a single result
But that's already it. You return a single result with several records. The result you pass to that MockResult constructor could look like this:
var result = ctx.newResult(BICYCLES.COL1, BICYCLES.COL2);
result.add(ctx.newRecord(BICYCLES.COL1, BICYCLES.COL2).values(1, 2));
result.add(ctx.newRecord(BICYCLES.COL1, BICYCLES.COL2).values(3, 4));
...

How to unit tests method returning Java string?

Hi I have plenty of methods which returns string which I need to unit tests. Now challenge for me is is how do I do code coverage? For e.g. My method looks like the following
Public String getSqlToDoXYZ(Myconfig config) {
StringBuilder sb = new StringBuilder() ;
sb.append( "SELECT BLAH BLAH");
sb.append("WHERE ABC="+config.getABC());
return sb.toString() ;
}
Please give your ideas how to unit tests such scenario? I am using mockito to do unit testing. I am new to both mockito and unit testing please guide. Thanks in advance.
As pointed elsewhere, using Strings for SQL statements is dangerous, regarding SQL injections.
That being said, you simply have to call the method, and compare the result to a String you build "by hand" :
public void testBuildSqlToDoXYZ() throws Exception {
WhateverYourObjectIs yourObject = new WhateverYourObjectIs();
MyConfig myConfig = new MyConfig();
myConfig.setABC("foo");
String sql = yourObject.getSqlToDoXYZ(myConfig);
assertEquals("SELECT BLAH BLAH WHERE ABC='foo'", sql);
}
Mockito would only be helpfull in this case if is impossible for you to create a "MyConfig" object by hand.
There might be something else in your code that makes that difficult, but you haven't really provided us enough info.
I can't see any difficulties to test a method that returns a string.
public void testSqlToDoXYZ()
{
MyObj testTarget = new MyObj(/*Parameters if needed*/);
Config config = new Config();
/*Config config = new ConfigMock();*/
String expectedResult = "SELECT BLAH BLACH WHERE ABC=123;";
assertEquals(epxectedResult, testTarget.getSqlToDoXYZ(config));
}
The key is, that you have to know your result. If the config.getABC() call could return different values, you have to make sure it always provides the same values for your test. So you might have to mock your config object or put fake data into your config provider.

Mocking HttpServletRequest using JMock

I am trying to Unit Test a method for which I need to create the object of the class using a constructor.This is how the constructor looks like :
public WebformsClinEventBusiness(Webform webForm, String dataEntryModel, String obsBatId) {
this.webformObj = webForm;
this.eventObj = webForm.getEvent(obsBatId);
this.progressNoteText = webForm.getProgressNoteNext();
this.formValues = webForm.getFormValues();
this.lastFormValues = webForm.getLastFormValues();
this.emptyFormValues = webForm.getEmptyFormValues();
this.formVersion = webForm.getFormVersion();
this.dataEntryModel = dataEntryModel;
this.headerValues = webForm.getHeaderValues();
this.OBS_BAT_ID = obsBatId;
this.userPreferences = (CompSoapUserPreferences)webForm.getRequest().getSession(false).getAttribute(userPreferences.getSESName());
}
The problem is in the last line. I have a mock webform object and have set the expectations like this:
one (mockWebForm).getRequest();
will(returnValue(mockRequest));
one (mockRequest).getSession(false);
will(returnValue(mockSession));
allowing (mockSession).getAttribute(_SES_NAME);
will(returnValue(mockCompSoapUserPreferences));
allowing (mockCompSoapUserPreferences).getSESName();
will(returnValue(_SES_NAME));
When the code hits webform.getRequest() instead of calling the mock it calls the actual method which returns null and I end up with a null pointer exception.
Any ideas ? I would really appreciate any input on this.
Thanks for your time !

Categories