How can I mock service with complex request in Mockito and JUint? - java

I have an interface:
public interface SenderService {
String send(long amount);
}
And I have an implementation of this interface:
public class SenderServiceAdapter implements SenderService {
private final ThirdPartyService thirdPartyService;
public SenderServiceAdapter(ThirdPartyService thirdPartyService) {
this.thirdPartyService = thirdPartyService;
}
#Override
public String send(long amount) {
ThirdPartyRequest thirdPartyRequest = new ThirdPartyRequest();
thirdPartyRequest.setAmount(amount);
thirdPartyRequest.setId(UUID.randomUUID().toString());
thirdPartyRequest.setDate(new Date());
ThirdPartyResponse thirdPartyResponse = thirdPartyService.send(thirdPartyRequest);
String status = thirdPartyResponse.getStatus();
if (status.equals("Error")) throw new RuntimeException("blablabla");
return thirdPartyResponse.getMessage();
}
}
Now I want to write Unit test for this service. I need to mock thirdPartyService's method send. But I don't understand how.
public class SenderServiceAdapterTest {
private ThirdPartyService thirdPartyService;
private SenderService senderService;
#Before
public void setUp() throws Exception {
thirdPartyService = Mockito.mock(ThirdPartyService.class);
senderService = new SenderServiceAdapter(thirdPartyService);
}
#Test
public void send() {
when(thirdPartyService.send(new ThirdPartyRequest())).thenReturn(new ThirdPartyResponse());
String message = senderService.send(100L);
}
}
The ThirdPartyRequest creates in SenderServiceAdapter. How can I mock it?

Try this:
doReturn(new ThirdPartyResponse()).when(thirdPartyService).send(any(ThirdPartyRequest.class));
Also by looking your code, you will need to set something in the response, so you will have to do this:
ThirdPartyResponse response = new ThirdPartyResponse(); //or mock
response.setStatus(...);
response.setMessage(...);
doReturn(response).when(thirdPartyService).send(any(ThirdPartyRequest.class));

Related

Mocking completable future

I am trying to create unit test for the following code. The code utilizes AWS Java 2 SDK. The code calls selectObjectContent in S3AsyncClient class which returns a CompletableFuture (https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html). My test is returning null pointer exception while invoking future.get()
Here is the method I want to unit test.
public <T> Collection<T> queryWithS3Select(
List<String> s3Keys,
String s3SelectQuery,
InputSerialization inputSerialization,
Class<T> modelObject,
Comparator<T> comparator
) throws ExecutionException, InterruptedException, IOException {
TreeSet<T> collection = new TreeSet<>(comparator);
List<SelectObjectContentRequest> selectObjectContentRequest =
buildS3SelectRequests(s3Keys, s3SelectQuery, inputSerialization);
S3SelectContentHandler s3SelectContentHandler = new S3SelectContentHandler();
StringBuilder selectionResult = new StringBuilder();
for (SelectObjectContentRequest socr : selectObjectContentRequest) {
CompletableFuture<Void> future = s3AsyncClient.selectObjectContent(socr, s3SelectContentHandler);
future.get();
s3SelectContentHandler.getReceivedEvents().forEach(e -> {
if (e.sdkEventType() == SelectObjectContentEventStream.EventType.RECORDS) {
RecordsEvent response = (RecordsEvent) e;
selectionResult.append(response.payload().asUtf8String());
}
});
}
JsonParser parser = objectMapper.createParser(selectionResult.toString());
collection.addAll(Lists.newArrayList(objectMapper.readValues(parser, modelObject)));
return collection;
}
My unit test so far. Running this code I get null pointer exception at future.get() line above. How can I use the mock s3AsyncClient to return a valid future?
#Mock
private S3AsyncClient s3AsyncClient;
#Test
public void itShouldReturnQueryResults() throws IOException, ExecutionException, InterruptedException {
List<String> keysToQuery = List.of("key1", "key2");
InputSerialization inputSerialization = InputSerialization.builder()
.json(JSONInput.builder().type(JSONType.DOCUMENT).build())
.compressionType(String.valueOf(CompressionType.GZIP))
.build();
Comparator<S3SelectObject> comparator =
Comparator.comparing((S3SelectObject e) -> e.getStartTime());
underTest.queryWithS3Select(keysToQuery, S3_SELECT_QUERY, inputSerialization, S3SelectObject.class, comparator );
}
Here is the S3SelectContentHandler
public class S3SelectContentHandler implements SelectObjectContentResponseHandler {
private SelectObjectContentResponse response;
private List<SelectObjectContentEventStream> receivedEvents = new ArrayList<>();
private Throwable exception;
#Override
public void responseReceived(SelectObjectContentResponse response) {
this.response = response;
}
#Override
public void onEventStream(SdkPublisher<SelectObjectContentEventStream> publisher) {
publisher.subscribe(receivedEvents::add);
}
#Override
public void exceptionOccurred(Throwable throwable) {
exception = throwable;
}
#Override
public void complete() {}
public List<SelectObjectContentEventStream> getReceivedEvents() {
return receivedEvents;
}
}
I will share unit test for similar functionality and show you how to work with completable future when your code has .join() to continue the execution
Code under test
private final S3AsyncClient s3AsyncClient;
public long getSize(final S3AsyncClient client, final String bucket, final String key) {
return client.headObject(HeadObjectRequest.builder().bucket(bucket).key(key).build()).join().contentLength();
}
and in this code the client.headObject() returns the CompletableFuture<HeadObjectResponse> which we are going to mock and test in Unit Test as shown below
#Test
#DisplayName("Verify getSize returns the size of the given key in the bucket")
void verifyGetSizeRetunsSizeOfFileInS3() {
CompletableFuture<HeadObjectResponse> headObjectResponseCompletableFuture =
CompletableFuture.completedFuture(HeadObjectResponse.builder().contentLength(20000L).build());
when(s3AsyncClient.headObject(headObjectRequestArgumentCaptor.capture()))
.thenReturn(headObjectResponseCompletableFuture);
long size = s3Service.getSize(s3AsyncClient, "somebucket", "someFile");
assertThat(headObjectRequestArgumentCaptor.getValue()).hasFieldOrPropertyWithValue("bucket", "somebucket")
.hasFieldOrPropertyWithValue("key", "someFile");
assertThat(size).isEqualTo(20000L);
}

In Java, How to test void method in Junit Mockito with assertion?

How to test void methods in Mockito with assertSame or assertEquals. I am able to do verify only.
i am getting sonar or PMD rules violation -"JUnit tests should include assert() or fail()".
Below is my sample class with test class.
#Service
public class MyServiceImpl implements IService {
#Autowired
private IDyDBDAO dyDBDAO;
#Override
public void update() {
dyDBDAO.save(getDetailData());
}
#Override
public List<Detail> getCurrentDetail() {
return getDetails(dyDBDAO.findAll());
}
private List<Detail> getDetails(Iterable<Detail> details) {
...blah...
}
private String getPlace(){
Places p = Places.getPlace();//static
return p == null? PlacesUtil.getName("DH"): p.getName;
}
private Detail getDetailData() {
Detail d = new Detail();
d.setName("blah");
d.setDesc("fsdfsdfdsf");
d.setPlace(getPlace());
return d;
}
}
#RunWith(PowerMockRunner.class)
#PrepareForTest({Places.class, PlacesUtil.class})
public class MyServiceImplTest {
#InjectMocks
private MyServiceImpl myServiceImpl;
#Mock
private IDyDBDAO dyDBDAO;
#Test
public void testGetCurrentDetail() {
given(dyDBDAO.findAll()).willReturn(getMockDetails());
assertSame(myServiceImpl.getCurrentDetail().size(), 2);
}
#Test
public void testUpdate() {
PowerMockito.mockStatic(Places.class);
// first update , second update -us-west-2 will update
given(Places.getPlace()).willReturn(PlacesUtil.getName("UH"))
.willReturn(null);
myServiceImpl.syncStatus();
// update again with DH
myServiceImpl.syncStatus();
verify(dyDBDAO, times(2)).save(any(Detail.class));
// how to assert checking here
}
private Iterable<Detail> getMockDetails() {
Detail d1 = new Detail();
d1.setName("blah");
d1.setDesc("fsdfsdfdsf");
d1.setPlace("sdfsdf");
Detail d2 = new Detail();
d2.setName("blahblah1");
d2.setDesc("e345345");
d2.setPlace("8907j");
List<Detail> listOfDetail = new ArrayList<>();
listOfDetail.add(eps1);
listOfDetail.add(eps2);
return listOfDetail;
}
}
You need to capture the value passed to the dao save method. Use mockito's ArgumentCaptor for that. Then assert on that value.
Something along these lines:
ArgumentCaptor<Detail> captor = ArgumentCaptor.forClass(Detail.class);
verify(dyDBDAO, times(2)).save(captor.capture());
Detail detail1 = captor.getValues().get(0)
assertEquals(expectedDetail, detail1)
I would assume that your void method that needs to be tested is update in MyServiceImpl.
Firstly, you can verify if dyDBDAO.save() is called.
Mockito.verify(dyDBDAO).save(Mockito.anyList...);
Secondly, you can check the modified or created records in the database by retrieving them and comparing to the inputs from getMockDetails.

Mocking builders in JUnit test

Let's say if I have a test that uses builders to construct objects. The problem is that the builder() method in the builder class is static.
Generally, mocking a static method is already an indicator of bad design. However, in the case of builders, the builder() methods are always static. What's the best approach to unit testing methods using builders()? Should the builders be refactored into a separate class to facilitate mocking?
class Service {
private SqsClient sqsClient;
private String sqsQueueUrl;
public Service(String sqsQueueUrl) {
this.sqsClient = SqsClient.builder().build();
this.sqsQueueUrl = sqsQueueUrl;
}
public SqsClient getClient() {
return this.client;
}
public SqsClient setClient(SqsClient client) {
this.client = client;
}
public String getSqsQueueUrl() {
return this.sqsQueueUrl;
}
public void setSqsQueueUrl(String sqsQueueUrl) {
this.sqsQueueUrl = sqsQueueUrl;
}
public void onEvent(Activity activity) {
// How to mock builders in unit test?
DeleteMessageRequest deleteRequest = DeleteMessageRequest.builder().queueUrl(this.sqsQueueUrl).receiptHandle(activity.getReceiptHandle()).build();
DeleteMessageResponse deleteMessageResponse = this.sqsClient.deleteMessage(deleteRequest);
}
}
class ServiceTest {
#Test
public void testEvent() {
String sqsQueueUrl = "http://127.0.0.1";
String receiptHandle = "asdasd";
SqsClient sqsClient = EasyMock.mock(SqsClient.class);
Service service = EasyMock.mock(Service.class);
// EasyMock expect and replay here.
service.setClient(sqsClient);
service.setSqsQueueUrl(sqsQueueUrl);
Activity activity1 = new Activity();
activity.setReceiptHandle(receiptHandle);
service.onEvent(activity);
}
}

Unit test android: How to return function not to be null when calls another function return and use

I have a FileRepository class to fill MutableLiveData. I have two functions in there. One is calling web service and setting list (getAllFilms). Other one is assigning MutableLiveData with first function List (getFilmData). I try to write unit test for MutableLiveData. Can you help me? This function data always comes null.
public class FilmRepositoryTest
#Mock
FilmRepository frepo;
#Rule
public InstantTaskExecutorRule instantTaskExecutorRule = new InstantTaskExecutorRule();
#Before
public void setUp() throws Exception {
}
#Test
public void getFilmData_forData() throws IOException {
ArrayList<film> filmlistesi = new ArrayList<>();
MutableLiveData<List<film>> bilgi = new MutableLiveData<>();
String arama = "ankara";
filmlistesi.add(new film("Behzat Ç.: Bir Ankara Polisiyesi","2010–2019","tt1795096","series","https://m.media-amazon.com/images/M/MV5BZDZjY2I5ZjEtZGE2MS00ZjRmLTlmMGEtMDQ5ZmZhZWJjYzk3XkEyXkFqcGdeQXVyNDg4MjkzNDk#._V1_SX300.jpg"));
when(frepo.getAllFilms(arama)).thenReturn(filmlistesi);
bilgi.setValue(filmlistesi);
System.out.println(frepo.getFilmData(arama)); // print(NULL)
System.out.println(bilgi.getValue()); // print(filmlistesi)
assertEquals(frepo.getFilmData(arama),bilgi.getValue());
}
public class FilmRepository
public MutableLiveData<List<film>> getFilmData(String a) throws IOException {
MutableLiveData<List<film>> data = new MutableLiveData<>();
data.setValue(getAllFilms(a));
return data;
}
public ArrayList getAllFilms(String filmName) throws IOException {
ArrayList<film> dataset = new ArrayList<>();
return dataset;
}
LiveData or MutableLiveData must have an Observer set of it or else it returns null
Observer<List<film>> observer = new Observer<List<film>>() {
#Override
public void onChanged(#Nullable List<film> films) {
assertEquals(frepo.getFilmData(arama), films.getValue());
biligi.removeObserver(this)
}
};
bilgi.observeForever(observer);
bilgi.setValue(filmlistesi);

How do I write this test case?

I am currently doing a small project on spring-mvc in my backend and I am trying to create tests for my converters and engines. Below is my BookmarkEngine.java file
#Service
public class BookmarkEngine implements IBookmarkEngine{
private static final String URL_PREFIX = "http://";
#Override
public String getFullUrl(String url) {
if(!url.startsWith(URL_PREFIX))
{
return URL_PREFIX + url;
}
return url;
}
}
How would I go about writing a test for this?
Here is my BookmarkEngineTest:
public class BookmarkEngineTest {
IBookmarkEngine bookmarkEngine = new BookmarkEngine();
private ViewBookmark defaultBookmark;
#Before
public void setUp() throws Exception {
defaultBookmark = new ViewBookmark();
defaultBookmark.setBookmarkId(1L);
defaultBookmark.setTitle("A sample bookmark");
defaultBookmark.setUrl("This is a sample bookmark.");
defaultBookmark.setAuthor(".");
defaultBookmark.setLastUpdated(1497812309081L);
}
#Test
public void getFullUrl() {
String result = bookmarkEngine.getFullUrl(defaultBookmark.getUrl());
assertThat(result.length(), is(defaultBookmark.getUrl().length()));
}
}
That certain test in getFullUrl() does not run, but how can I can make it work?
You can make a test to see if the strings will match such as
#Test
public void getFullUrl() {
String testurl = "facebook.com";
String testurl2 = "http://facebook.com";
assertEquals(bookmarkEngine.getFullUrl(testurl),"http://facebook.com");
assertEquals(bookmarkEngine.getFullUrl(testurl2),"http://facebook.com");
}

Categories

Resources