I want to throw a ContentIOException from a method whose signature look like this.
public void putContent(InputStream is) throws ContentIOException.
When I try to throw ContentIOException from Mockito like such:
when(StubbedObject.putContent(contentStream)).thenThrow(ContentIOException.class);
I get the following compilation error:
The method when(T) in the type Mockito is not applicable for the arguments (void).
What am I doing wrong?
Take a look at this reference in the official API. You want to reverse the way your call is made and adjust the argument too, since this is a void method that you expect to throw an exception.
doThrow(new ContentIOException()).when(StubbedObject).putContent(contentStream);
You can use following code
when(testRepositoryMock.findOne(123)).thenThrow(new NullPointerException());
Then after you can check your logic
String erroResponse= service.testMethodForResponse(accountNum);
JSONObject jsonObj = new JSONObject(erroResponse);
String _acNo = jsonObj.getString("accountNum");
assertEquals(accountNum, _acNo);
}
If you are using Spring boot then add top of class
#SpringBootTest
#RunWith(MockitoJUnitRunner.class)
Inside of class you need to inject object
#InjectMocks //actual object you want to get test coverage
private TestService testService;
#Mock //Mock object which call by actual object for mocking
private testRepository testRepositoryMock;
Reference link :http://www.baeldung.com/mockito-behavior
Related
Basically, I'm trying to set the result of a final method. The method is simple, like this:
#NotNull
public final Server getServer() {
return this.server;
}
I mock it like this:
EasyMock.expect(object.getServer()).andReturn(server);
Where server is a POJO. This throws this:
java.lang.IllegalStateException: incompatible return value type
at org.easymock.internal.MocksControl.andReturn(MocksControl.java:281)
For that line.
I tried not using a POJO for server, and mocking it instead.
#Mock
private Server server = mock(Server.class);
Yet still the same error. I'm absolutely positive that they are the exact same type. Why is this happening?
Now, for some reason I get a different error:
java.lang.IllegalStateException: no last call on a mock available
Same code, all I have is this:
#Test
public void test() {
EasyMock.expect(object.getServer()).andReturn(server);
replayAll();
TestedObject.useObject(object);
}
The reason you get an error when mocking a final method is that it is not supported by EasyMock. https://easymock.org/user-guide.html#mocking-limitations
Final methods cannot be mocked. If called, their normal code will be executed.
You can use PowerMock to mock final and static methods.
I faced next issue when I have been writing Junit tests with using Mockito. My test invokes methods on real object instead mock object and I receive NullPointerException. Here is my code:
public class JSFUtilsTest {
public JSFUtilsTest() { }
JSFUtils jsfUtils = mock(JSFUtils.class);
FacesContext facesContext = ContextMocker.mockFacesContext();
ExternalContext extContext = mock(ExternalContext.class);
Application app = mock(Application.class);
ExpressionFactory exFactory = mock(ExpressionFactory.class);
ELContext elContext = mock(ELContext.class);
ValueExpression valExp = mock(ValueExpression.class);
#Test
public void testResolveExpression() {
when(jsfUtils.resolveExpression("expression")).thenAnswer(new Answer<Object>(){
public Object answer(InvocationOnMock invocation){
when(facesContext.getApplication()).thenReturn(app);
when(app.getExpressionFactory()).thenReturn(exFactory);
when(facesContext.getELContext()).thenReturn(elContext);
when(exFactory.createValueExpression(elContext, "expression", Object.class)).thenReturn(valExp);
when(valExp.getValue(elContext)).thenReturn(anyObject());
return valExp.getValue(elContext);
}
});
jsfUtils.resolveExpression(anyString());
verify(jsfUtils).resolveExpression(anyString());
assertNotNull(jsfUtils.resolveExpression(anyString()));
}
}
Instead calling resolveExpression() on Mock, I have got calling on JSFUtils object. JSFUtils.java and JSFUtilsTest.java are located in different packages. Can anybody help me? Thanks in advance!
I assume that this is just an example and in real test you do not call methods on the mock directly, but inject the dependencies to OUT.
You are expecting your mock to answer when you are calling jsfUtils.resolveExpression("expression"). In fact you are not calling it. I would suggest to change it to jsfUtils.resolveExpression(anyString()) and if you need it to be called with some specific string, you can check it the verify block: verify(jsfUtils).resolveExpression("expression");
Also calling jsfUtils.resolveExpression(anyString()); is not the right approach. Method anyString() is designed for stubbing not for real call.
Instead calling resolveExpression() on Mock, I have got calling on JSFUtils object.
Then do not create a mock, but a spy:
//JSFUtils jsfUtils = mock(JSFUtils.class);
JSFUtils jsfUtils = spy(new JSFUtils(/* mocks of dependencies if needed */));
But this is only needed if want to mock the return value of some other method in your class under test to force isolation of your unit.
This is not the case in your example as far as I see. So just write:
//JSFUtils jsfUtils = mock(JSFUtils.class);
JSFUtils jsfUtils = new JSFUtils(/* mocks of dependencies if needed */);
#Test
public void testResolveExpression() {
when(jsfUtils.resolveExpression("expression")).thenAnswer(new Answer<Object>(){
public Object answer(InvocationOnMock invocation){
when(facesContext.getApplication()).thenReturn(app);
when(app.getExpressionFactory()).thenReturn(exFactory);
when(facesContext.getELContext()).thenReturn(elContext);
when(exFactory.createValueExpression(elContext, "expression", Object.class)).thenReturn(valExp);
when(valExp.getValue(elContext)).thenReturn(anyObject());
return valExp.getValue(elContext);
}
});
jsfUtils.resolveExpression(anyString());
verify(jsfUtils).resolveExpression(anyString());
assertNotNull(jsfUtils.resolveExpression(anyString()));
This does not make any sense:
You mock the method of your class under test (cut) and then call that very same method. This way you do not verify the behavior of your cut but the behavior of the mocking framework.
Also you call the method twice within the same test method. You should avoid that.
You should change your test to this:
#Test
public void testResolveExpression() {
// arrange (test case specific setup of mocks and DTOs)
when(facesContext.getApplication()).thenReturn(app);
when(app.getExpressionFactory()).thenReturn(exFactory);
when(facesContext.getELContext()).thenReturn(elContext);
when(exFactory.createValueExpression(elContext, "expression", Object.class)).thenReturn(valExp);
when(valExp.getValue(elContext)).thenReturn(anyObject());
// act (call real method on real object)
Object result = jsfUtils.resolveExpression("a valid input");
// assert
assertNotNull(result );
}
I m trying to mock an interface.
public interface FlowCopyParamsBusinessManager {
List<FlowCopyParams> findByAppli(String application, String sourcePattern)
throws FlowCopyParamsBusinessException;
}
In my code, when i call this method findByAppli, i would like to return a list of FlowCopyParams.
List<FlowCopyParams> lstFlowCopyParams = flowCopyParamsBusinessManager.findByAppli(
"TOTO","TATA);
Here my try in the class test:
#BeforeClass
public static void mockBeanIn() throws Exception {
List<FlowCopyParams> flowCopyParamsList = new ArrayList<>();
PowerMockito.spy(FlowCopyParamsBusinessManager.class);
PowerMockito.when(FlowCopyParamsBusinessManager.class, "findByAppli", Mockito.anyString(), Mockito.anyString()).thenReturn(flowCopyParamsList);
}
I have this error :
java.lang.IllegalArgumentException: object is not an instance of declaring class
I don't know why because the method findByAppli must have two string parameters, and i put Mockito.anyString() and i still have IllegalArgumentException.
Any clue ?
Thxs.
You don't need to use PowerMockito, and as its an Interface, theres no need to spy() as you are not relying on any non mocked logic.
It can be done like this, in your test class define a class variable.
private FlowCopyParamsBusinessManager flowCopyParamsBusinessManagerMock;
In an #Before annotated method:
flowCopyParamsBusinessManagerMock = Mockito.mock(FlowCopyParamsBusinessManager.class);
List<FlowCopyParams> flowCopyParamsList = new ArrayList<>();
when(flowCopyParamsBusinessManagerMock
.findByAppli(Mockito.anyString(), Mockito.anyString()).thenReturn(flowCopyParamsList);
Then refer to flowCopyParamsBusinessManagerMock in your tests.
My test did not work because I was trying to spy the class and not on the instance of FlowCopyParamsBusinessManager.class .
First , we have to create the mock :
FlowCopyParamsBusinessManager mockFlowCopyParamsBusinessManager = PowerMockito.mock(FlowCopyParamsBusinessManager.class);
Then , spy the instance :
PowerMockito.spy(mockFlowCopyParamsBusinessManager);
PowerMockito.when(mockFlowCopyParamsBusinessManager, "findByAppli", Mockito.anyString(), Mockito.anyString()).thenReturn(flowCopyParamsList);
It works as well !
I did this put this #RunWith(PowerMockRunner.class) at the top of the class. then mock Object with PowerMockito.mock(MyMock.class); This way use can mock a interface or final class.
I have a class LoggerInterceptor with an InvocationContext as parameter.
For this class I am trying to write a unit test but I am stuck on the first line:
public class LoggerInterceptor{
public method log(InvocationContext context) {
String name = invocationContext.getTarget().getClass().getName();
.....
}
My test looks like this:
#Test
public void logTest() throws Exception {
LoggerInterceptor objectToTest = new LoggerInterceptor();
InvocationContext context = Mockito.mock(InvocationContext.class);
Object target = Mockito.mock(Object.class);
Mockito.when(context.getTarget()).thenReturn(target);
MockGateway.MOCK_GET_CLASS_METHOD = true;
Mockito.doReturn(objectToTest.getClass()).when(target).getClass();
MockGateway.MOCK_GET_CLASS_METHOD = false;
objectToTest.log(context);
}
I am getting a UnfinishedStubbingException when I call the method log(context).
If I try with:
Mockito.when(target.getClass()).thenReturn(objectToTest.getClass());
I get this exception:
The method thenReturn(Class<capture#3-of ? extends Object>) in the type OngoingStubbing<Class<capture#3-of ? extends Object>> is not applicable for the arguments (Class<capture#4-of ? extends LoggerInterceptor>)
Is there any way I can pass this first line? The String that I get back is not important.
Object.getClass() is final. Final methods can't be mocked or stubbed with Mockito, because the compiler sees "final", skips the virtual method dispatch, and consequently Mockito can neither intercept calls to the method nor identify the method in doReturn, when, or verify. When you interact with Mockito later, it detects that you started stubbing but cannot detect that you finished, so it throws an UnfinishedStubbingException.
If you want to have target adjust the type or types it appears as, you'll need to change the class object passed into Mockito.mock, or add withSettings().extraInterfaces(...).
It looks like EasyMock version 3.2 now supports using annotations to setup mock objects. I am new to EasyMock (and Java in general) and am trying to understand how to use this. Do these annotations do something new or just provide an alternative way to do things? The documentation says:
Since EasyMock 3.2, it is now possible to create mocks using annotations. This is a nice
and shorter way to create your mocks and inject them to the tested class.
Here is the example above, now using annotations: ...
Then there is a listing that shows use of the #TestSubject and #Mock annotations, but I don't understand how it works. It seems as if it magically sets the private field of the class under test to the mock object. In most of my cases, I just want to make mock objects that return pre-defined values for use in JUnit test cases (don't currently care about verifying which ones were called, how many times they were called, etc). For example, for some tests I want to create a fake HttpServletRequest object like this:
public class SomeTest {
// Construct mock object for typical HTTP request for the URL below
private static final String REQUEST_URL = "http://www.example.com/path/to/file?query=1&b=2#some-fragment";
private static final Map<String, String> requestHeaderMap;
static {
Map<String, String> requestHeaders = new LinkedHashMap<String, String>();
requestHeaders.put("host", "www.example.com");
// ... (add any other desired headers here) ...
requestHeaderMap = Collections.unmodifiableMap(requestHeaders);
}
private HttpServletRequest httpServletRequest;
// ...
#Before
public void setUp() throws Exception {
httpServletRequest = createNiceMock(HttpServletRequest.class);
expect(httpServletRequest.getRequestURI()).andReturn(REQUEST_URL).anyTimes();
expect(httpServletRequest.getHeaderNames()).andReturn(Collections.enumeration(requestHeaderMap.keySet())).anyTimes();
capturedString = new Capture<String>();
expect(httpServletRequest.getHeader(capture(capturedString))).andAnswer(new IAnswer<String>() {
public String answer() throws Throwable {
String headerName = capturedString.getValue().toLowerCase();
if (requestHeaderMap.containsKey(headerName))
return requestHeaderMap.get(headerName);
else
return "";
}
}).anyTimes();
replay(httpServletRequest);
// ...
}
#Test
public void someMethod_givenAnHttpServletRequest_shouldDoSomething() {
// ...
}
}
Could I change the above code to use annotations? If so, should I? Under what circumstances?
I thought perhaps putting the #Mock annotation above an instance variable declaration would automatically take care of the createNiceMock(...) part, but this does not seem to work, so I suspect that I am misunderstanding something.
Examining their source code, they are using reflection to inject anything with an #Mock into a field of the #TestSubject. Their javadoc for the method
public static void injectMocks(final Object obj)
in EasyMockSupport.java says:
Inject a mock to every fields annotated with {#link Mock} on the class passed in parameter. Then, inject these mocks to the fields of every class annotated with TestSubject.
The rules are
Static and final fields are ignored
If a mock can be assigned to a field, do it. The same mock an be assigned more than once
If no mock can be assigned to a field, skip it silently
If two mocks can be assigned to the same field, return an error
Fields are searched recursively on the superclasses
Note: If the parameter extends EasyMockSupport, the mocks will be created using it to allow replayAll/verifyAll to work afterwards
#param obj the object on which to inject mocks
#since 3.2
public static void injectMocks(final Object obj) {
...
}
For you to use the #Mock annotation, you would need a #TestSubject that has an HttpServletRequest field for EasyMock to set the #Mock on (via reflection). The annotations are provided to make it a little easier to wire up a test, it let's you skip the createMock, and then calling the settter yourself.