I have such code fragment:
#Test
public void itShouldInvokeExecuteMethod() {
when(dbHandlerService.getQuery(anyMap(), anyString())).thenReturn(anyString());
dbHandlerController.createSchema(new HashMap<String, String>());
verify(dbHandlerService).execute(anyString());
}
When I run tests, the InvalidUseOfMatchersException occurs in line
when(dbHandlerService.getQuery(anyMap(), anyString())).thenReturn(anyString());
What I'm doing wrong?
You need to return a concrete value. anyString() in thenReturn is wrong.
Try
when(dbHandlerService.getQuery(anyMap(), anyString())).thenReturn("");
Related
//Original method:
#Autowired
private ConversionServiceValidator validator;
public CRSConversionResult convertCRS(ConvertCrsVo convertCrsVo) throws Exception {
if (validator.isSameSourceAndTarget(convertCrsVo))
throw new ValidationException(Constants.BADREQUEST);
if (convertCrsVo.getPreferredTransforms() != null) {
List<TransformVo> preferredTransformList = new ArrayList<>();
for (TransformVo transformVo : convertCrsVo.getPreferredTransforms()) {
preferredTransformList.add(getPerfByCode(transformVo));
}
convertCrsVo.setPreferredTransforms(preferredTransformList);
}
convertCrsVo.setSourceCRS(getCrsVoByCode(convertCrsVo.getSourceCRS()));
convertCrsVo.setTargetCRS(getCrsVoByCode(convertCrsVo.getTargetCRS()));
convertCrsVo = validator.replaceCoordinates(convertCrsVo);
logger.info("ShellGeodeticService::convertCRS::Request to GeoCalService convertpoints::" + mapper.writeValueAsString(convertCrsVo));
ConvertPointsResponse response = geoCalService.convertCRS(convertCrsVo);
CRSConversionResult result = new CRSConversionResult();
result.setCriteriaMessage(response.getCriteriaMessage());
result.setResultPoints(response.getResultPoints());
result.setTransformName(response.getTransformName());
result.setTransformDescription(response.getTransformDescription());
// added schema as per pbi 195298
List<ConvertedTransformsResult> transformsResults = new ArrayList<>();
if (response.getTransforms() != null || !response.getTransforms().isEmpty())
response.getTransforms().stream().forEach(
t -> transformsResults.add(new ConvertedTransformsResult().getConvertedTransformsResult(t)));
result.setTransforms(transformsResults);
String logmessage=generateLogMessage(result,convertCrsVo);
logger.info(logmessage);
validator.isResponseValid(result);
return result;
}
//The testcase for the above method
#Test
public void testconvertCRSJob() throws Exception{
ConvertCrsVo convertCrsVo = TestDataFactory.getConvertCrsVo();
CRSConversionResult crsConversionResult = TestDataFactory.getCRSConversionResult();
ConversionServiceValidator conversionServiceValidatorMock = mock(ConversionServiceValidator.class);
Mockito.when(geoCalService.convertCRS(Mockito.any()))
.thenReturn(TestDataFactory.getConvertPointsResponse(convertCrsVo));
Mockito.when(validator.replaceCoordinates(convertCrsVo))
.thenReturn(TestDataFactory.getConvertCrsVo());
Mockito.when(geoCalService.search(Mockito.any(SearchFilter.class)))
.thenReturn(TestDataFactory.getSearchResultResponseForCRS());
Mockito.when(shellGeodeticService.convertCRS(convertCrsVo))
.thenReturn(TestDataFactory.getCRSConversionResult());
shellGeodeticService.convertCRSJob();
}
The error that i am getting is as below:
org.mockito.exceptions.misusing.CannotStubVoidMethodWithReturnValue:
'isResponseValid' is a void method and it cannot be stubbed with a return value!
Voids are usually stubbed with Throwables:
doThrow(exception).when(mock).someVoidMethod();
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. The method you are trying to stub is overloaded. Make sure you are calling the right overloaded version.
2. Somewhere in your test you are stubbing final methods. Sorry, Mockito does not verify/stub final methods.
3. A spy is stubbed using when(spy.foo()).then() syntax. It is safer to stub spies -
- with doReturn|Throw() family of methods. More in javadocs for Mockito.spy() method.
4. Mocking methods declared on non-public parent classes is not supported.
at com.shell.geodetic.GeodeticConvertionApiAppTests.testconvertCRSJob(GeodeticConvertionApiAppTests.java:1783)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
Can someone help me on how to stub the void method "isResponseValid" ? I tried around 100 combinations that i saw in SOF and nothing worked. Thanks for the help in advance.
*Edit
Class ConversionServiceValidator {
public void isResponseValid(CRSConversionResult response) throws InvalidDataException {
if (response.getResultPoints().isEmpty() || response.getResultPoints() == null) {
throw new ValidationException("Request body has incorrect format");
} else {
for (Point point : response.getResultPoints()) {
if (point.getX().trim().equals("0") || point.getY().trim().equals("0")) {
throw new InvalidDataException(400, "Bad Request", "WARNING: Not all points could be converted",
response);
}
}
}
It is a mock #InjectMocks ShellGeodeticService shellGeodeticService;
shellGeodeticService is not a mock. #InjectMocks is used for the class under test, where the mocks are injected into.
That implies you can not use
Mockito.when(shellGeodeticService.convertCRS(convertCrsVo))
.thenReturn(TestDataFactory.getCRSConversionResult());
in your test as only mocks(or spys) can be used within Mockito.when.
Actually im trying to run test case for shellGeodeticService.convertCRS() and since it calls isResponseValid method internally , i have to mock that also right?
No, that is incorrect. If validator is a mock every method invocation will do nothing by default. So, unless you want to throw an exception, you do not need to define anything.
As your question lacks some details, I assume a complete version of your test could be similiar to this:
#InjectMocks
ShellGeodeticService shellGeodeticService;
#Mock
ConversionServiceValidator validator;
#Mock
... geoCalService; // some unknown class
#Test
public void testconvertCRSJob() throws Exception{
ConvertCrsVo convertCrsVo = TestDataFactory.getConvertCrsVo();
// Note sure whether this is correct by your logic as there is no `replacement` happening.
Mockito.when(validator.replaceCoordinates(convertCrsVo)).thenReturn(convertCrsVo);
Mockito.when(geoCalService.convertCRS(Mockito.any())).thenReturn(TestDataFactory.getConvertPointsResponse(convertCrsVo));
CRSConversionResult result = shellGeodeticService.convertCRS();
// do some assertions on the result
}
As validator is a mock:
validator.isSameSourceAndTarget(convertCrsVo) returns false be default
validator.isResponseValid( ... ) does nothing by default
As you did not add the methods getCrsVoByCode, getPerfByCode and generateLogMessage take note that if there are any further interactions with the mocked objects you'll need to add them.
(eg.: a call to geoCalService.search is not visible in your test code, so I removed the behaviour definition from the test displayed above)
The context
I have a simple method that I'm testing using the mockito library.
The problem
I have a error:
"[MockitoHint] ReceiveServiceTest.testGetFileDto (see javadoc for MockitoHint):
[MockitoHint] 1. Unused... -> at .ReceiveServiceTest.testGetFileDto(ReceiveServiceTest.java:46)
[MockitoHint] ...args ok? -> at ReceiveService.getFileDto(ReceiveService.java:28)
I dont understand way.
The code
#RunWith(MockitoJUnitRunner.class)
public class ReceiveServiceTest {
private List<File> filePaths = new ArrayList<>();
#InjectMocks
private ReceiveService receiveService;
#Mock
private FindFiles findfiles;
#Mock
private ReadByte readByte;
#Before
public void before() {
filePaths.add(new File("d://folder//test1_message_received"));
filePaths.add(new File("d://folder//test2_message_received"));
filePaths.add(new File("d://folder//test3_message_received"));
}
#Test
public void testGetFileDto() throws IOException {
// Given
byte[] resultByteArr = new byte[1028];
when(findfiles.getPathFiles()).thenReturn(filePaths);
when(readByte.readByteArrFromFile(new File("d://folder//test3_message_received"))).thenReturn(resultByteArr);
List<MessageDTO> result = receiveService.getFileDto();
//some assert
}
method
#Autowired
private FindFiles findFiles;
#Autowired
private ReadByte readByte;
public List<MessageDTO> getFileDto() throws IOException {
List<MessageDTO> fileDtos = new ArrayList<>();
for (File file : findFiles.getPathFiles()) {
fileDtos.add(new MessageDTO(Base64.getEncoder().encode(readByte.readByteArrFromFile(new File(file.getPath()))),
file.getName(), "zip", null));
}
return fileDtos;
}
I think mocks are not being initialized. Please initialize the mocks in the #Before method.
#Before
public void init() {
initMocks(this);
}
This should solve the problem I guess.
Here is solution for my problem. I added foreach loop. Now the mock works, but byte [] is different than what it should return.
// Given
byte[] mockByteArr = new byte [2048];
when(findfiles.getPathFiles()).thenReturn(filePaths);
for (File filePath : filePaths) {
when(readByte.readByteArrFromFile(new File(filePath.getPath()))).thenReturn(mockByteArr);
}
//When
List<MessageDTO> result = receiveService.getFileDto();
//Then
assertEquals(3, result.size());
assertEquals(mockByteArr, result.get(1).getContent());
Your problem is, that you create a new object in the following line:
when(readByte.readByteArrFromFile(new File("d://folder//test3_message_received"))).thenReturn(resultByteArr);
Mockito needs to know which real object is passed to the method so that it can return the appropriate thenReturn-value. So if you pass the actual reference into it, your code will work, but also only if you specify all the values which are listed. Otherwise you may get a NullPointerException.
By the way, calling new File(file.getPath()) seems redundant to me. You can just use file instead.
So with the following your code might work better:
when(readByte.readByteArrFromFile(filePaths.get(0)).thenReturn(resultByteArray);
but then you need to specify it for all entries.
Alternatively, use a Matcher instead:
when(readByte.readByteArrFromFile(ArgumentMatchers.any(File.class))).thenReturn(resultByteArr);
or specify the actual argument matching you require as matchers can be very powerful in that regard.
Previously the answer contained the following, which is still true, but not as concise as the answer above:
It's been a long time since I last used mocks (and I am even proud of it ;-)).
The message already states that one should consult the javadoc and there I found the following:
Those are hints - they not necessarily indicate real problems 100% of the time.
Nonetheless, I believe the problem is with the following statement:
when(readByte.readByteArrFromFile(new File("d://folder//test3_message_received"))).thenReturn(resultByteArr);
I think you need to specify a return for every entry in the filePaths or make the call more generic using Matchers.any() (or any other appropriate Matcher).
Getting a null pointer exception on Mockito.when for the below code line.
when(entityManager.createQuery(any(String.class)).setParameter(any(String.class), any(String.class)).getSingleResult()).thenReturn("2");
Trying to mock entity manager which is declared as
#Mock
private EntityManager entityManager;
Any help to resolve this?
Complete test class
#RunWith(MockitoJUnitRunner.class)
public class ASDAOImplTest {
#InjectMocks
ASDAOImpl asdaoImpl=new ASDAOImpl();
#Mock
private EntityManager entityManager;
#Before
public void setUp()
{
ReflectionTestUtils.setField(asdaoImpl,"capLimit", 1);
}
#Test
#Ignore
public void validateCappingTest()
{
when(entityManager.createQuery(any(String.class)).setParameter(any(String.class), any(String.class)).getSingleResult()).thenReturn("2");
asdaoImpl.validateCapping("2");
}
}
Edit: Ah, spoke to soon. The error is here...
when(entityManager.createQuery(any(String.class)).setParameter(...)
entityManager is a mock. Per default, a mock will return null. So, entityManager.createQuery(...) will return null. Calling setParameter on null is a NPE.
What you need to insert is a query mock...
#Mock
private Query query;
...
// when createQuery is called, return the mocked query object (instead of null)
when(entityManager.createQuery(any(String.class)).thenReturn(query);
// make sure that setParameter returns this query object back (would otherwise also be NPE)
when(query.setParameter(any(String.class), any(String.class)).thenReturn(query);
// And return the desired result from getSingleResult
when(query.getSingleResult()).thenReturn("2");
Old answer:
Hard to say without the complete code, but a guess would be that you are misssing the Mockito initialization (the part that actually creates object for the variables annotated with #Mock). This can be done in at least two ways:
// Run the whole test with the Mockito runner...
#RunWith(MockitoJUnitRunner.class)
public class MyTestClass { ...
or...
// Do the Mockito initialization "manually"
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
Both ways will lead to Mockito creating all the objects where the variables are annotated with #Mock (it also handles #InjectMocks, etc.).
If this doesn't help, you will have to post more of your test class, otherwise probably noone can help.
I'm testing a void method that happens to call several other void methods in a class (all of these methods are in the same class). The method is something along these lines...
public void methodToTest() {
methodA();
methodB();
}
void methodA() {
methodA1();
methodA2();
methodA3();
}
What I'd like to do is cause methodA() above to do nothing. That is, I want methodA() to basically be like this:
void methodA() { }
I've tried both doThrow() and doAnswer() on methodA() to no avail. It's as if those are both being completely ignored.
An example of what I've tried...
doThrow(new RuntimeException()).when(mockedClass).methodA();
Is there a way to do this just using Mockito? I'm not at liberty to change the class that's being modified.
If you are looking to have methodB still execute, while methodA does nothing. This will do that:
TestClass spy = spy(new TestClass());
doNothing().when(spy).methodA();
spy.methodToTest();
#Mock
ApplicationClass applicationClass;
Mockito.doNothing().when(applicationClass).myMethod(Matchers.any(Object.class));
I'm writing unit tests in JUnit, but have not been able to successfully cover a branch of a particular method that catches a SQLException and returns a null object.
This is the class I'm testing:
#Component
public class UnitOfMeasureRowMapper implements RowMapper<UnitOfMeasure> {
public UnitOfMeasure mapRow(final ResultSet resultSet, final int rowNumber) throws SQLException {
UnitOfMeasure unitOfMeasure = new UnitOfMeasure();
try {
unitOfMeasure.setUnitOfMeasureId(resultSet.getInt("UNITOFMEASUREID"));
unitOfMeasure.setOwnerUserId(resultSet.getInt("USERID"));
unitOfMeasure.setName(resultSet.getString("NAME"));
unitOfMeasure.setDescription(resultSet.getString("DESCRIPTION"));
} catch (SQLException e) {
unitOfMeasure = null;
}
return unitOfMeasure;
}
}
This is the JUnit test that I have written to cover the second branch of the above method (with appropriate context from the test class):
private static UnitOfMeasure testUnitOfMeasure;
private static UnitOfMeasureRowMapper mockRowMapper;
public void setUp() throws Exception {
mockRowMapper = mock(UnitOfMeasureRowMapper.class);
mockResultSet = mock(ResultSet.class);
}
#Test(expected=SQLException.class)
public void testUnitOfMeasureRowMapperFailsSQLException() throws SQLException {
when(mockRowMapper.mapRow(mockResultSet, 1)).thenReturn(null);
testUnitOfMeasure = mockRowMapper.mapRow(mockResultSet, 1);
}
I think the problem is with the last line; somehow I need to force a SQLException. The problem is, I don't know how and haven't been able to find an answer. Can anyone help?
If I understand the question well, the class under test is UnitOfMeasureRowMapper. If this is true, then you don't want to mock it in your test, otherwise you are testing a mock!
What is under test in your JUnit, is the behavior of UnitOfMeasureRowMapper#mapRow when ResultSet you give it throws a SQLException during the execution of the method. Then you want this method to return null.
I would write it like this:
private ResultSet mockResultSet;
private RowMapper<UnitOfMeasure> rowMapper = new UnitOfMeasureRowMapper();
public void setUp() throws Exception {
mockResultSet = mock(ResultSet.class);
}
#Test
public void mapRow_SHOULD_return_null_WHEN_resultSet_throws_a_SQLException() {
when(mockResultSet.getInt(anyString()).thenThrow(new SQLException());
assertThat(mockRowMapper.mapRow(mockResultSet, 1), nullValue());
}
As suggested Samuel in his answer, you may set one of the method of the result set you use to throw a SQLException, and then check in your JUnit that the mapRow method returns null as expected. Here you are not testing the behavior of the result set, so its fine to mock it to achieve a behavior it would normally have under some circunstancies that would be painful to obtain otherwise. Mocking the result set behavior lets you focus on testing the RowMapper behavior.
You are testing the UnitOfMeasureRowMapper that implements RowMapper. So have a rowMapper property in your JUnit, and I prefer to see it through its interface. I like to brutally call the constructor of UnitOfMeasureRowMapper because I want to keep my JUnit as simple as they can be.
Set one of the methods (maybe getInt?) of your mock ResultSet to throw the exception. You didn't specify what mocking framework you're using so I can't tell you the exact syntax.