I am trying to test a simple log in servlet that I have created with Mockito. I've been doing a bit of research on it, and I feel as though what I have written should work, but I am getting an "org.mockito.exceptions.base.MockitoException"
Here is my test class:
#RunWith(GwtMockitoTestRunner.class)
public class LoginServletTest {
#Test
public void testLogInServlet() throws Exception {
final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
final HttpServletResponse response =
Mockito.mock(HttpServletResponse.class);
when(request.getParameter("username")).thenReturn("testuser");
when(request.getParameter("password")).thenReturn("testpass");
final StringWriter stringWriter = new StringWriter();
final PrintWriter writer = new PrintWriter(stringWriter);
when(response.getWriter()).thenReturn(writer);
new LogInServlet().doPost(request, response);
assertTrue(stringWriter.toString().contains("My expected string"));
}
I am getting this exception:
org.mockito.exceptions.base.MockitoException:
ClassCastException occurred while creating the mockito proxy :
class to mock : 'javax.servlet.http.HttpServletRequest', loaded by classloader : 'sun.misc.Launcher$AppClassLoader#18b4aac2'
created class : '$javax.servlet.http.HttpServletRequest$$EnhancerByMockitoWithCGLIB$$d31fd980', loaded by classloader : 'org.mockito.internal.creation.util.SearchingClassLoader#fbd1f6'
proxy instance class : null
instance creation by : ObjenesisInstantiator
You might experience classloading issues, disabling the Objenesis cache *might* help (see MockitoConfiguration)
at com.mypackage.mywidget.mywidget.LoginServletTest.<init>(LoginServletTest.java:50)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:195)
at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:244)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:241)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at com.google.gwtmockito.GwtMockitoTestRunner.run(GwtMockitoTestRunner.java:373)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.ClassCastException: $javax.servlet.http.HttpServletRequest$$EnhancerByMockitoWithCGLIB$$d31fd980 cannot be cast to org.mockito.cglib.proxy.Factory
at org.mockito.internal.creation.cglib.ClassImposterizer.createProxy(ClassImposterizer.java:143)
at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:58)
at org.mockito.internal.creation.cglib.ClassImposterizer.imposterise(ClassImposterizer.java:49)
at org.mockito.internal.creation.cglib.CglibMockMaker.createMock(CglibMockMaker.java:24)
at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33)
at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59)
at org.mockito.Mockito.mock(Mockito.java:1285)
at org.mockito.Mockito.mock(Mockito.java:1163)
... 24 more
The line that causes this error is:
final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
I am new to mockito, but from what I gather this error mean that mockito is having trouble mocking the HttpServletRequest. I am not sure why or what I can do to fix this. Any help would be appreciated.
I tried to replicate your issue. It seems to work fine
Can you try the following code?
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
#RunWith(MockitoJUnitRunner.class)
public class LoginServletTest {
class LogInServlet extends HttpServlet {
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("My expected string");
}
}
#Test
public void testLogInServlet() throws Exception {
final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
final HttpServletResponse response = Mockito.mock(HttpServletResponse.class);
when(request.getParameter("username")).thenReturn("testuser");
when(request.getParameter("password")).thenReturn("testpass");
final StringWriter stringWriter = new StringWriter();
final PrintWriter writer = new PrintWriter(stringWriter);
when(response.getWriter()).thenReturn(writer);
new LogInServlet().doPost(request, response);
assertTrue(stringWriter.toString().contains("My expected string"));
}
}
If you have still the exception, please update your post accordingly
Related
I'm trying to revive an older java repo that needs some changes to be made. I am no java pro by far, but alas it must be done.
The repo specifies OpenJDK-14.0.1 and Gradle-6.5 but I have decided to get it running on a newer version of Java and Gradle so that the next poor soul that comes along may have an easier chance of getting setup.
As such I've gone with OpenJDK-19.0.1 and Gradle-7.5.1 and expectedly there have been some issues.
One being the compile configuration having been removed from Gradle-7.5.1 replaced with implementation and the second needing to update the version for Lombok to a higher version so I have gone with 1.18.24
Now the repo builds and 321 of 330 tests pass with 9 failing. This is where I am stuck. All the failing tests are all in the same file and fail because of the same error. Not being a java pro this error doesn't mean much to me.
So my questions is what causes this error in Java and how is it fixed?
The error and a stripped back version of the code with only one of the failing tests is supplied below.
ERROR
java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: module java.base does not "opens java.util" to unnamed module #48cf768c
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
at org.junit.contrib.java.lang.system.EnvironmentVariables.getFieldValue(EnvironmentVariables.java:136)
at org.junit.contrib.java.lang.system.EnvironmentVariables.getEditableMapOfVariables(EnvironmentVariables.java:98)
at org.junit.contrib.java.lang.system.EnvironmentVariables.access$000(EnvironmentVariables.java:34)
at org.junit.contrib.java.lang.system.EnvironmentVariables$EnvironmentVariablesStatement.restoreOriginalVariables(EnvironmentVariables.java:82)
at org.junit.contrib.java.lang.system.EnvironmentVariables$EnvironmentVariablesStatement.evaluate(EnvironmentVariables.java:73)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at jdk.internal.reflect.GeneratedMethodAccessor124.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy2/jdk.proxy2.$Proxy5.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
CODE
package com.pastoralcare.filter;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.util.UUID;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.EnvironmentVariables;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.authenticator.AuthenticationTokenAuthenticator;
import com.authenticator.InterServiceTokenAuthenticator;
import com.authorization.CheckStaffPermissions;
import com.dto.PermissionSetCodeDto;
import com.model.AuthToken;
import com.pastoralcare.constant.RestAPIConstants;
import com.pastoralcare.dto.AuthTokenDto;
import com.pastoralcare.dto.PermissionSetCodesDto;
import com.pastoralcare.dto.TokenDto;
#RunWith(SpringRunner.class)
public class TokenFilterTest {
#InjectMocks
TokenFilter tokenFilter;
#Mock
TokenDto tokenDto;
#MockBean
FilterChain filterChain;
#Mock
PermissionSetCodesDto permissionSetCodesDto;
#Mock
AuthTokenDto authTokenDto;
#Mock
InterServiceTokenAuthenticator internalAuth;
#Mock
AuthenticationTokenAuthenticator authnValidator;
#Mock
CheckStaffPermissions checkStaffPermissions;
#Mock
AuthToken authToken;
#Mock
PermissionSetCodeDto permissionSetCodeDto;
MockHttpServletRequest httpServletRequest = new MockHttpServletRequest();
MockHttpServletResponse httpServletResponse = new MockHttpServletResponse();
#Rule
public final EnvironmentVariables environmentVariables = new EnvironmentVariables();
PermissionSetCodesDto permissionSetsDto;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
// tokenFilter = new TokenFilter();
tokenFilter.tokenDto = mock(TokenDto.class);
UUID communityId = UUID.randomUUID();
UUID tenantId = UUID.randomUUID();
tokenFilter.tokenDto.setTenantId(tenantId);
tokenFilter.tokenDto.setCommunityId(communityId);
tokenFilter.tokenDto.setFirstName("name");
tokenFilter.tokenDto.setLastName("surname");
tokenFilter.tokenDto.setTimezoneIanaCode("UTC");
ReflectionTestUtils.setField(tokenFilter, "interServiceAuthKey", "8Y419dV49Jw+yeRho5iUIgLErSztNnlWvfmc2vzi8D8=");
ReflectionTestUtils.setField(tokenFilter, "activeProfile", "activeProfile");
RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(httpServletRequest));
}
#Test
public void testDoFilterActuator() throws ServletException, IOException {
httpServletRequest.setRequestURI("/actuator/");
MockHttpServletResponse mockResp = new MockHttpServletResponse();
FilterChain mockFilterChain = Mockito.mock(FilterChain.class);
tokenFilter.doFilter(httpServletRequest, mockResp, mockFilterChain);
assertEquals(200, mockResp.getStatus());
}
}
By massive coincidence I actually ran into the issue myself a few days after commenting, and thus had to solve it.
I had to replace the old Mockito library with the newer 'inline' version. This can be found at https://mvnrepository.com/artifact/org.mockito/mockito-inline
This version no longer attempts to do things that Java 17 doesn't allow anymore while trying to create a Mock object.
I'm trying to get rid of PowerMock and replace it with mockito-inline new feature Mocking object construction ,
as I can't refactor the old source code.
One of the test classes I have is mocking FileInputStream,
the class under test FileViewer
import java.awt.Button;
import java.awt.Event;
import java.awt.Font;
import java.awt.TextArea;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class FileViewer extends java.awt.Frame {
private static final long serialVersionUID = 1L;
Button close;
GUIListener fGuiListener;
public FileViewer() {
super();
fGuiListener = new GUIListener();
addWindowListener(fGuiListener);
}
public FileViewer(String filename) throws IOException {
super("FileViewer: " + filename);
fGuiListener = new GUIListener();
addWindowListener(fGuiListener);
File f = new File(filename);
int size = (int) f.length();
int bytes_read = 0;
byte[] data = new byte[size];
try (FileInputStream in = new FileInputStream(f)) {
while (bytes_read < size)
bytes_read += in.read(data, bytes_read, size - bytes_read);
}
TextArea ta = new TextArea(new String(data, 0), 24, 80);
ta.setFont(new Font("Helvetica", Font.PLAIN, 12));
ta.setEditable(false);
this.add("Center", ta);
close = new Button("Close");
this.add("South", close);
this.pack();
this.show();
}
public boolean action(Event e, Object what) {
if (e.target == close) {
this.hide();
this.dispose();
return true;
} else
return false;
}
}
and the original unit test using powermock was
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.FileInputStream;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#PowerMockIgnore({ "javax.management.*", "javax.security.*" })
#RunWith(PowerMockRunner.class)
#PrepareForTest({ FileViewer.class, FileInputStream.class, java.awt.Frame.class })
public class FileViewerTest {
String dir = System.getProperty("user.dir");
String fileName = "/testFiles/testRead.txt";
FileInputStream mockStream = null;
#Before
public void setup() throws Exception {
mockStream = Mockito.mock(FileInputStream.class);
when(mockStream.read(any(byte[].class), anyInt(), anyInt())).thenReturn(2000);
PowerMockito.whenNew(FileInputStream.class).withAnyArguments().thenReturn(mockStream);
}
#Test
public void testFileViewer_wFilename() throws Exception {
FileViewer spy = Mockito.spy(new FileViewer(dir + fileName));
verify(mockStream, times(1)).close();
spy.dispose();
}
}
I tried to follow the example Mock Java Constructors With Mockito | Configuration and Examples
and creat a new unit test using MockedConstruction as the following
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.FileInputStream;
import org.junit.Test;
import org.mockito.MockedConstruction;
import org.mockito.Mockito;
public class FileViewerMockitoTest {
String dir = System.getProperty("user.dir");
String fileName = "/testFiles/testRead.txt";
#Test
public void testFileViewerWithFilename() throws Exception {
try (MockedConstruction<FileInputStream> mocked = Mockito.mockConstruction(FileInputStream.class,
(mock, context) -> {
// further stubbings ...
when(mock.read(any(), any(), any())).thenReturn((int) new File(dir + fileName).length() + 1);
})) {
FileViewer cut = new FileViewer(dir + fileName);
verify(mocked, times(1)).close();
cut.dispose();
}
}
}
But I got the following Exception
org.mockito.exceptions.base.MockitoException: Could not initialize mocked construction
at java.io.FileInputStream.<init>(FileInputStream.java)
at sun.misc.URLClassPath$FileLoader$1.getInputStream(URLClassPath.java:1385)
at sun.misc.Resource.cachedInputStream(Resource.java:77)
at sun.misc.Resource.getByteBuffer(Resource.java:160)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
at com.cds.nrd.xss.util.FileViewerMockitoTest.testFileViewerWithFilename(FileViewerMockitoTest.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:43)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.Iterator.forEachRemaining(Iterator.java:116)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:82)
at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:73)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:756)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.NullPointerException
at com.cds.nrd.xss.util.FileViewerMockitoTest.lambda$0(FileViewerMockitoTest.java:27)
at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker$InlineConstructionMockControl.lambda$enable$0(InlineByteBuddyMockMaker.java:710)
at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.lambda$new$3(InlineByteBuddyMockMaker.java:272)
at org.mockito.internal.creation.bytebuddy.MockMethodAdvice.handleConstruction(MockMethodAdvice.java:176)
at org.mockito.internal.creation.bytebuddy.inject.MockMethodDispatcher.handleConstruction(MockMethodDispatcher.java:53)
... 57 more
Any idea about the reason of the exception or how to make it work, or any alternate approach?
Found the solution:
We can't set any() parameter in the stub of the lambda function in try-with-resource
(in your case, when(mock.read(any(), any(), any())) in FileViewerMockitoTest), which will cause mock.read(any(), any(), any()) to throw an NPE: "could not unbox null" (don't know what it means).
Just simply replace (all of) these arguments to something like any(ArgClass.class), will solve the NPE problem, so do with the Could not initialize mocked construction MockitoException problem.
(How did I find the problem? By extracting the lambda function as a method, we can get the real description of the NPE in the debug environment.)
(I was surprised that there was no information on the internet other than this question.)
I am trying to run a BooResourcesT test class from within IntelliJ Idea and I am getting the "Failed to load ApplicationContext" exception.
Please look at my code::
package lms.co;
import static org.hamcrest.CoreMatchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationContextLoader;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.fasterxml.jackson.databind.ObjectMapper;
import lms.co.controller.BooksResourceImpl;
import lms.co.model.Book;
import lms.co.repository.BookRepository;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = LMSApplication.class, loader = SpringApplicationContextLoader.class)
#WebAppConfiguration
public class BooksResourceITTest {
private MockMvc mockMvc;
#Autowired
private BookRepository booksRepo;
#Autowired
private ObjectMapper mapper;
private BooksResourceImpl booksResource;
#Before
public void setup(){
MockitoAnnotations.initMocks(this);
booksResource = new BooksResourceImpl();
mockMvc = MockMvcBuilders.standaloneSetup(booksResource).build();
ReflectionTestUtils.setField(booksResource, "booksRepo", booksRepo);
}
#Test
public void addBookTest() throws Exception{
Book book = new Book("isbn1","Test1","Test Author","","","","","");
String body = mapper.writeValueAsString(book);
mockMvc.perform(post("/api/book")
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.content(body))
.andExpect(status().isCreated());
}
#Test
public void getBookByIsbnTest() throws Exception {
Book book = new Book("isbn2","Test2","Test Author","","","","","");
booksRepo.addBook(book);
MvcResult result = mockMvc.perform(get("/api/book/isbn2")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.title",is("Test2")))
.andReturn();
}
#Test
public void getBooksTest() throws Exception {
Book book1 = new Book("isbn3","Test3","Test Author","","","","","");
booksRepo.addBook(book1);
Book book2 = new Book("isbn4","Test4","Test Author","","","","","");
booksRepo.addBook(book2);
MvcResult result = mockMvc.perform(get("/api/books")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$[*].title", hasItems("Test4", "Test3")))
.andReturn();
}
}
Error is
java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:94)
at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:170)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:110)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor': Invocation of init method failed; nested exception is java.lang.NoClassDefFoundError: javax/xml/bind/ValidationException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
... 24 more
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/ValidationException
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:800)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:698)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:621)
... 56 more
I am new in spring project and this is my 1st time of getting this type error so please help me and please don't close my question if their is an para mistakes.Please...
I have created an rest api and tested via postman and able to get success response as expected. Now i have created Junit test case for the above api but while executing getting "java.lang.AssertionError: Status expected:<200> but was:<415> ". Not able to figure out why this exception is happening.
I'm new to both Mockito and MockMVC so any help would be appreciated.
Below is my test class
package com.example.demo.hystricks;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.io.Serializable;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import org.apache.commons.lang.SerializationUtils;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.example.demo.DemoController;
import com.example.demo.DemoService;
import com.example.demo.InputModel;
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = DemoController.class)
public class DemoControllerTest {
private MockMvc mockMvc;
#InjectMocks
private DemoController demoController;
#MockBean
private DemoService demoService;
#MockBean
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
DemoController demoController = new DemoController(demoService);
this.mockMvc = MockMvcBuilders
.standaloneSetup(demoController).
setMessageConverters(mappingJackson2HttpMessageConverter).build();
}
#Test
public void postData() throws Exception {
InputModel inputModel = new InputModel("12345","Test","CSC",getEventTime());
System.out.println("before api....");
RequestBuilder requestBuilder = MockMvcRequestBuilders.post("/demoService")
.accept(MediaType.APPLICATION_JSON)
.content(inputModel.toString())
.contentType(MediaType.APPLICATION_JSON);
mockMvc.perform(requestBuilder)
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk());
System.out.println("after api....");
}
private LocalDateTime getEventTime() {
Instant instant = Instant.ofEpochMilli(Instant.now().toEpochMilli());
LocalDateTime eventTimestamp = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
return eventTimestamp;
}
}
My Rest Controller
#RestController
public class DemoController {
private static final Logger LOGGER = LoggerFactory.getLogger(DemoController.class);
public final DemoService demoService;
public DemoController(DemoService demoService) {
this.demoService = demoService;
}
#RequestMapping(value = "demoService",method = RequestMethod.POST)
public ResponseEntity<String> postData(
#RequestBody InputModel inputModel){
LOGGER.info("DemoService Entered successfully");
demoService.postData(inputModel.getId(),inputModel.getName(),
inputModel.getDepartment(), inputModel.getJoinDate());
LOGGER.info("DemoService Exited successfully");
return new ResponseEntity<String>("success",HttpStatus.OK) ;
}
}
Console Message before api:
>2018-10-16 12:15:49.391 WARN 6200 --- [ main] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported]
2018-10-16 12:15:49.437 INFO 6200 --- [ Thread-3] o.s.w.c.s.GenericWebApplicationContext : Closing org.springframework.web.context.support.GenericWebApplicationContext#5023bb8b: startup date [Tue Oct 16 12:15:48 IST 2018]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext#76a4ebf2
Failure Stack Trace:
>java.lang.AssertionError: Status expected:<200> but was:<415>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:619)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at com.example.demo.hystricks.DemoControllerTest.postData(DemoControllerTest.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
The issue is on this line:
#MockBean
private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter;
You are mocking this converter. Create a instance using new instead:
this.mockMvc = MockMvcBuilders
.standaloneSetup(controller).
setMessageConverters(new MappingJackson2HttpMessageConverter()).build();
Or as rightly mentioned by M. Dienum, you can do away with the below 2 lines from setUp() method and it'll work:
DemoController demoController = new DemoController(demoService);
this.mockMvc = MockMvcBuilders
.standaloneSetup(demoController).
setMessageConverters(mappingJackson2HttpMessageConverter).build();
After doing all this if you run into 400 error then your toString() method isn't producing valid json.
I was trying to write unit test for Servlet using sprint-test using
mock object
my maven dependency is:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.0.3.RELEASE</version>
</dependency>
I want to test just java servlet like below following book PRACTICAL TDD AND ACCEPTANCE TDD
FOR JAVA DEVELOPER :
package sample;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginServlet extends HttpServlet {
private boolean isValid;
/**
*
*/
private static final long serialVersionUID = 2473252741884321641L;
#Override
public void init() throws ServletException {
super.init();
}
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
String user = req.getParameter("j_username");
String pass = req.getParameter("j_password");
if (isValidLogin(user, pass)) {
resp.sendRedirect("/frontpage");
req.getSession().setAttribute("username", user);
} else {
resp.sendRedirect("/invalidlogin");
}
}
private boolean isValidLogin(String user, String pass) {
return isValid;
}
public void setValid(boolean isValid) {
this.isValid = isValid;
}
}
My code is:
package sample;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
public class SprintTestProb {
#Test
public void wrongPasswordShouldRedirectToErrorPage() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.addParameter("j_username", "gyanu");
request.addParameter("j_password", "wrongpassword");
LoginServlet login = new LoginServlet();
login.setValid(false);
login.doPost(request, response);
assertEquals("/invalidlogin", response.getRedirectedUrl());
}
}
I got error on line MockHttpServletResponse response = new MockHttpServletResponse();
as follows:
java.lang.ExceptionInInitializerError
at org.springframework.mock.web.MockHttpServletResponse.<init>(MockHttpServletResponse.java:76)
at sample.SprintTestProb.wrongPasswordShouldRedirectToErrorPage(SprintTestProb.java:14)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.util.MissingResourceException: Can't find bundle for base name javax.servlet.LocalStrings, locale en_US
at java.util.ResourceBundle.throwMissingResourceException(ResourceBundle.java:1499)
at java.util.ResourceBundle.getBundleImpl(ResourceBundle.java:1322)
at java.util.ResourceBundle.getBundle(ResourceBundle.java:721)
at javax.servlet.ServletOutputStream.<clinit>(ServletOutputStream.java:87)
... 25 more
I need to replace dependency for javaee-api with javax.selvlet-api as below:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
According to the Spring Framework Reference for Testing you should be using annotations to autowire your mocks. The example in the spring reference:
`
#WebAppConfiguration
#ContextConfiguration
public class WacTests {
#Autowired WebApplicationContext wac; // cached
#Autowired MockServletContext servletContext; // cached
#Autowired MockHttpSession session;
#Autowired MockHttpServletRequest request;
#Autowired MockHttpServletResponse response;
#Autowired ServletWebRequest webRequest;
//...
}
`
A different example (without annotations) can be found here
I had a similar issue and solved it by adding this dependency to my pom and there is no need to change your javaee-api to javax.servlet
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>servlet-api-2.5</artifactId>
<version>6.1.11</version>
</dependency>