Mockito cannot mock a static method - java

I don't know what's wrong with my code, none of my static method can be mocked by Mockito...
I have checked for couple of hours, and it seems that I have nothing wrong in my code.
here is the dependency:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>3.12.4</version>
<scope>test</scope>
</dependency>
here is the static method:
public class FakeTokenUtil {
public static String getToken(){
return "123123123123";
}
}
here is the test class:
#RunWith(MockitoJUnitRunner.class)
public class TokenTest {
#Test
public void mockStatic() {
MockedStatic<FakeTokenUtil> mock=Mockito.mockStatic(FakeTokenUtil.class);
mock.when(FakeTokenUtil::getToken).thenReturn("666666");
System.out.println(FakeTokenUtil.getToken());
}
}
after running the test, I got this exception:
org.mockito.exceptions.base.MockitoException:
The used MockMaker SubclassByteBuddyMockMaker does not support the creation of static mocks
Mockito's inline mock maker supports static mocks based on the Instrumentation API.
You can simply enable this mock mode, by placing the 'mockito-inline' artifact where you are currently using 'mockito-core'.
Note that Mockito's inline mock maker is not supported on Android.
at com.test.myapp.service.TokenTest.mockStatic(TokenTest.java:13)
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:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.mockito.internal.runners.DefaultInternalRunner$1$1.evaluate(DefaultInternalRunner.java:55)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
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.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:100)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:107)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:41)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

From the doc:
Try to add a file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker with a single line
mock-maker-inline
This feature comes at a slight performance cost, though. I usually try to avoid this kind of mocking. Maybe you should reconsider your code, too. if it is a simple and predictable utility method, there is no need to mock it for a test. If it is rather a dependency to another component, then it should be an instance method.

Related

Struts 2.5 running Junit 4 test and getting runtime errors finding a Struts plugin parent package

struts version: 2.5.25 - using the REST plugin
Junit 4.12
I am trying to setup the unit testing framework to begin testing struts actions and having issues getting a basic test to run. It is currently complaining that it cannot find the parent package "jinjava" (this is a custom struts plugin which builds and runs fine outside of the unit test)
Is there anything that needs to be configured for the struts configuration to load the struts plugins? Below is my current setup, along with the error I am seeing when the test is run.
Stack Trace:
com.opensymphony.xwork2.config.ConfigurationException: Unable to load configuration.
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:69)
at org.apache.struts2.dispatcher.Dispatcher.getContainer(Dispatcher.java:970)
at org.apache.struts2.dispatcher.Dispatcher.init_PreloadConfiguration(Dispatcher.java:463)
at org.apache.struts2.dispatcher.Dispatcher.init(Dispatcher.java:496)
at org.apache.struts2.util.StrutsTestCaseHelper.initDispatcher(StrutsTestCaseHelper.java:44)
at org.apache.struts2.StrutsJUnit4TestCase.initDispatcher(StrutsJUnit4TestCase.java:256)
at org.apache.struts2.StrutsJUnit4TestCase.setUp(StrutsJUnit4TestCase.java:245)
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.RunBefores.evaluate(RunBefores.java:24)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
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:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
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:191)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
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.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)
Caused by: com.opensymphony.xwork2.config.ConfigurationException: Parent package is not defined: jinjava
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.buildPackageContext(XmlConfigurationProvider.java:689)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.addPackage(XmlConfigurationProvider.java:539)
at com.opensymphony.xwork2.config.providers.XmlConfigurationProvider.loadPackages(XmlConfigurationProvider.java:326)
at org.apache.struts2.config.StrutsXmlConfigurationProvider.loadPackages(StrutsXmlConfigurationProvider.java:108)
at com.opensymphony.xwork2.config.impl.DefaultConfiguration.reloadContainer(DefaultConfiguration.java:196)
at com.opensymphony.xwork2.config.ConfigurationManager.getConfiguration(ConfigurationManager.java:66)
... 42 common frames omitted
Unit Test (spring beans are configured via annotations, we are not using any xml)
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = LoginActionSpringConfig.class)
public class LoginActionTest extends IwsStrutsSpringTestCase<LoginAction> {
#Test
public void getActionMapping() {
ActionMapping mapping = getActionMapping("/security/login");
Assert.assertNotNull(mapping);
Assert.assertEquals("/security", mapping.getNamespace());
Assert.assertEquals("login", mapping.getName());
}
}
Below is the IwsStrutsSpringTestCase super class that is extending StrutsSpringJUnit4TestCase. I have supplied a getConfigPath() including also attempting to put struts-plugin.xml in.
public abstract class IwsStrutsSpringTestCase<T> extends StrutsSpringJUnit4TestCase<T> {
#Override
protected String getConfigPath() {
return "struts.xml, struts-plugin.xml";
}
}
Below is the struts-plugin.xml from the jinjava plugin that is being complained about in the stack trace
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
<constant name="struts.jinjava.basepath" value="WEB-INF/jinJava" />
<package name="jinjava" extends="struts-default">
<result-types>
<result-type name="jinjava" class="com.hs.struts.result.JinJavaResult" />
</result-types>
</package>
</struts>
update 10/18/2020
pom.xml I would also like to note that the webapp directory is not following the default maven layout. The web files are stored under /web
update 11/1/2020
Below is my LoginActionSpringConfig.class as requested
#Configuration
public class LoginActionSpringConfig {
#Bean
public IIwsAuthenticationService authenticationService() {
return new IwsAuthenticationServiceTest();
}
#Bean
public ISecurityLogDao securityLogDao() {
return new SecurityLogDaoTest();
}
#Bean
public IUsersDepartmentDao usersDepartmentDao() {
return new UsersDepartmentDaoTest();
}
#Bean
public IDepartmentDao departmentDao() {
return new DepartmentDaoTest();
}
#Bean
public IwsCookieInterface iwsCookie() {
return new IwsCookieTest();
}
}
I don't know the specific answer on why the above configuration was not working, but I got past my initial problem. I tried overriding the getConfigPath() originally due to seeing these FileNotFoundExceptions
java.io.FileNotFoundException: class path resource [WEB-INF/content/audit/] cannot be resolved to URL because it does not exist
I am using the struts-rest plugin which utilizes the convention plugin which was throwing these errors. I took a step back and removed the getConfigPath() override. After some additional research and found a SO post that suggested overriding the default struts.convention.result.path in the struts.xml and pointing it at the package for the action classes to satisfy the convention plugin. We are not using the convention plugin in this way for our results, so this is only being done to satisfy the convention plugin during unit testing.
<constant name="struts.convention.result.path" value="/com/hs/iws/actions" />
I am now experiencing a different issue, but will start a new post.

NoClassDefFoundError ErrorCoded

I am trying to run a JUnit test in my Spring Boot app, but I am getting the NoClassDefFoundError shown below.
Both the spring-boot-starter-parent and spring-boot-starter-test (v2.0.5.RELEASE) are in the pom.xml file. I added the spring-core (v5.0.9.RELEASE) in as well.
Apparently, the ErrorCoded class has been deprecated as of 4.3.6, so I'm not sure how to find out why the test runner (or other library) is still trying to load this class.
Here is my test class:
#RunWith(SpringJUnit4ClassRunner.class)
public class SystemBuilderTest {
private System system;
#Before
public void setUp() throws Exception {
StatefulConnection conn = new StatefulConnection.Builder(null)
.build();
Device d1 = new SensingDevice.Builder("sensor1", conn)
.build();
system = new System.SystemBuilder("testSystem")
.addChildDevice(d1)
.build();
system.initialize();
}
#Test
public void testStart() throws DCFDeviceException {
system.start();
assertTrue(system.getName().equals("testSystem"));
assertTrue(system.getChildDevices().size() == 1);
assertTrue(system.getChildDevices().iterator().next().getName().equals("sensor1"));
}
}
... and the stack trace:
java.lang.NoClassDefFoundError: org/springframework/core/ErrorCoded
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1007)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:801)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:699)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:622)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:580)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1007)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:801)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:699)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:622)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:580)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
at org.springframework.context.support.GenericApplicationContext.<init>(GenericApplicationContext.java:110)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:115)
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:275)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:251)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)
at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117)
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)
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:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: java.lang.ClassNotFoundException: org.springframework.core.ErrorCoded
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
... 50 common frames omitted
Something in your build is pulling in a dependency on spring-test 4.3.x (not sure what minor release, but it shouldn't be relevant.)
The reason I say this is because the line numbers in the stack trace do not align with the line numbers in the SpringJUnit4ClassRunner class in the 5.x releases.
From your stack trace:
at o.s.t.c.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:227)
That indicates that at line 227 there should be a call to a createTest method. You can see that this is true in the 4.3.x branch version of this class.
But in the 5.0.x branch version, line 227 is instead a call to getTestContextManager().prepareTestInstance(testInstance);.
This is pretty conclusive. So if your IDE is telling you otherwise (as you indicated in another comment), it is wrong. Or you might need to do a 'clean' on your project, if the IDE supports that functionality.
Since you did not post your full pom it is not possible to tell you what is pulling in the old dependency. However, you should be able to figure it out by using the Maven dependency plugin:
mvn dependency:tree
This command will print the dependency hierarchy in tree form. I recommend redirecting output to file and grepping for spring-test. That will allow you to identify the problematic dependency and use a maven <exclusion> to disallow the problematic dependency.
I cannot answer this exactly why is it error but I can tell that you have the conflict in version of some dependency.
As you can see in the document below(although you use version 2.0.5.RELEASE).
https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/htmlsingle/
ErrorCoded is used by SpringJUnit4ClassRunner but if you see in their Github, SpringJUnit4ClassRunner does not use ErrorCoded anymore in version 5.0.8 of org.springframework.spring-test.
You have to see if your Spring project really uses which version of org.springframework.spring-test because SpringJUnit4ClassRunner is in that jar.
Hope this helps.
Can you pleaser un your test with SpringRunner.class and #SpringBootTest will load all required test dependencies.
#RunWith(SpringRunner.class)
#SpringBootTest
public class SystemBuilderTest {
For me happened to be older version of spring-test pulled by the spring-security-test. I am using spring-boot 2.x.
λ mvn dependency:tree | grep test
[INFO] +- org.springframework.security:spring-security-test:jar:4.2.3.RELEASE:test
[INFO] | \- org.springframework:spring-test:jar:4.3.9.RELEASE:test
Updating spring-security and spring-security-test to 5.x fixed it.
<properties>
<java.version>1.8</java.version>
<spring.version>2.0.4.RELEASE</spring.version>
<logging.version>2.8.2</logging.version>
<spring-security-test.version>5.0.6.RELEASE</spring-security-test.version>
<spring-security-config.version>5.0.6.RELEASE</spring-security-config.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring-security-config.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security-config.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>${spring-security-test.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

Spring boot mock CREATED POST response

Completely new to spring-boot.
I am trying to write a test for my POST method that returns a response of CREATED with the path of the resource. I am coming across all sorts of problems for something that I was assuming is very straight forward. In the code bellow is my current test class which seems to be crashing with a
ClassNotFoundException
on the first line of my method.
#RunWith(SpringRunner.class)
#WebMvcTest(AResource.class)
public class AResourceTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private AResource aResourceMock;
#Test
public void testPOST() throws Exception {
Response.ResponseBuilder created = Response.created(UriBuilder.fromPath("/123").build());
when(aResourceMock.create(123)).thenReturn(created.build());
mockMvc.perform(MockMvcRequestBuilders
.request(HttpMethod.POST, "/account")
.content("{\t\"id\": \"123\"}"))
.andExpect(MockMvcResultMatchers.status().isCreated());
}
}
Any idea how to properly mock my response? Thanks
EDIT:
stacktrace bellow
java.lang.RuntimeException: java.lang.ClassNotFoundException: com.sun.ws.rs.ext.RuntimeDelegateImpl
at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:122)
at javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:91)
at javax.ws.rs.core.UriBuilder.newInstance(UriBuilder.java:69)
at javax.ws.rs.core.UriBuilder.fromPath(UriBuilder.java:111)
at com.powerman.RestController.AResourceTest.canPOST(AResourceTest.java:34)
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:497)
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.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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.ClassNotFoundException: com.sun.ws.rs.ext.RuntimeDelegateImpl
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at javax.ws.rs.ext.FactoryFinder.newInstance(FactoryFinder.java:62)
at javax.ws.rs.ext.FactoryFinder.find(FactoryFinder.java:155)
at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:105)
... 34 more
I will add my dependencies in case they help at all:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.0.1.RELEASE</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.17.1</version>
</dependency>
</dependencies>
I'm not sure what you are trying to do and why you would want to mock the Response. When you are running a a test for your resources, generally wha you want to do is run integration tests. What this entails is making an actual request to the endpoint using a client library. MockMvc only works when you are using Spring MVC as the REST framework. But in your case, you are using Jersey (I assume, based on the jax-rs tag in your post.
As far as the client library, you can use the Jersey/JAX-RS Client API or you can use Spring Boot's TestRestTemplate, like they do in the official Spring Boot/Jersey sample project. For checking the created URI for the POST/Created resource, what you should be doing is checking the Location header in the response. This is was is set on the server side when you do Response.created(URI). For example, say this is your resource
#Path("customers")
public class CustomersResource {
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response createCustomer(Customer customer, #Context UriInfo uriInfo) {
int customerId = // create customer and get the resource id
UriBuilder builder = uriInfo.getAbsolutePathBuilder();
builder.path(Integer.toString(customerId));
return Response.created(builder.build()).build();
}
}
Jersey will automatically set the Location to value of the URI passed to created()
Then (if you're using the Jersey Client), then your test might look something like
#RunWith(SpringRunner.class)
#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ExampleResourceTest {
#LocalServerPort
private int port;
private Client client = ClientBuilder.newClient();
#Test
public void testCustomerLocationOnPost() {
Customer customer = new Customer("Jane", "Doe");
URI resourceUri = UriBuilder.fromUri("http://localhost")
.port(port).path("api").path("customers").build();
Response response = client.target(resourceUri).request().post(Entity.json(customer));
// test that we get the correct status code
assertThat(response.getStatus())
.isEqualTo(Response.Status.CREATED.getStatusCode());
// test that the location header is correct.
assertThat(response.getHeaderString(HttpHeaders.LOCATION))
.isEqualTo(UriBuilder.fromUri(resourceUri).path("123").build().toString());
}
}
As far as the dependencies, to use Jersey with Spring Boot you need to use the spring-boot-started-jersey dependency. Also get rid of the jersey-core dependency you have. See the linked project above for complete example.
Try adding to your pom.xml:
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>2.27</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-common</artifactId>
<version>2.27</version>
<scope>provided</scope>
</dependency>

Tests do not run when dependency on mockito-core present

I've added mockito-core to my dependencies but I seem to be unable to run tests (errors when running) unless I also add powermock-api-mockito to the dependencies. I start getting errors immediately after I put in the mockito-core dependency - no other changes are necessary (e.g. I don't need to add code that uses Mockito to start seeing errors).
Dependency I want to add:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.10.19</version>
<scope>test</scope>
</dependency>
Dependency I seem to need to include along:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
<scope>test</scope>
</dependency>
Without the above second dependency, I get the following errors. Again, this is purely dependency changes, no code changes:
java.lang.NoClassDefFoundError: org/hamcrest/TypeSafeMatcher
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:467)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:368)
And this:
java.lang.NoClassDefFoundError: org/junit/internal/matchers/StacktracePrintingMatcher
at org.junit.matchers.JUnitMatchers.isThrowable(JUnitMatchers.java:103)
at org.junit.rules.ExpectedExceptionMatcherBuilder.build(ExpectedExceptionMatcherBuilder.java:27)
at org.junit.rules.ExpectedException.handleException(ExpectedException.java:252)
at org.junit.rules.ExpectedException.access$000(ExpectedException.java:106)
at org.junit.rules.ExpectedException$ExpectedExceptionStatement.evaluate(ExpectedException.java:241)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
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 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
This should be solved by using mockito-all instead of mockito-core. It would have all the dependency required by mockito. hamcrest and junit are part of it.
Mockito-core 1.10.19 has no dependencies to the powermock-api-mockito. The only dependencies it has are following runtime dependencies:
org.hamcrest » hamcrest-core 1.1
org.objenesis » objenesis 2.1
Maybe these are conflicting with another library you have in your dependencies tree. Try to analyze your dependency tree using:
mvn dependency:tree
https://mvnrepository.com/artifact/org.mockito/mockito-core/1.10.19

No such method error while using RestAssuredMockMvc

I'm using RestAssuredMockMvc for unit testing spring mvc controllers.
This is my code:
import com.xyz.api.controller.UserController;
import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc;
import org.junit.Before;
import org.junit.Test;
import javax.servlet.http.HttpServletResponse;
import static org.hamcrest.Matchers.equalTo;
public class UserControllerRest {
private String userName = "xyz#example.com";
private String expectedResult = "Hello " + userName;
#Before
public void initialize() {
RestAssuredMockMvc.standaloneSetup(new UserController());
}
#Test
public void checkResponseAndBody() throws Exception {
RestAssuredMockMvc.given().param("userName", userName).when().get("/users").print();
RestAssuredMockMvc.given().param("userName", userName).when().get("/users").then().assertThat().statusCode(200).and().body(equalTo(expectedResult));
}
}
The first statement in checkResponseAndBody() prints: Hello xyz#example.com
But the second line gives the following error:
java.lang.NoSuchMethodError: com.jayway.restassured.internal.ValidatableResponseOptionsImpl.<init>(Ljava/lang/String;Lcom/jayway/restassured/internal/ResponseParserRegistrar;Lcom/jayway/restassured/config/RestAssuredConfig;Lcom/jayway/restassured/response/Response;Lcom/jayway/restassured/response/ExtractableResponse;)V
at com.jayway.restassured.module.mockmvc.internal.ValidatableMockMvcResponseImpl.<init>(ValidatableMockMvcResponseImpl.java:37)
at com.jayway.restassured.module.mockmvc.internal.MockMvcRestAssuredResponseImpl.then(MockMvcRestAssuredResponseImpl.java:36)
at com.giddh.api.restassured.UserControllerRest.checkResponseAndBody(UserControllerRest.java:25)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
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 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
I've seen the examples and even tried using the same code but still the error persists. How can I solve this?
You've probably not added all dependencies to your classpath. As indicated by the download page you also need to download and put the contents of rest-assured-2.5.0-dist.zip in your classpath.
If you're using Maven it should be enough to just depend on the spring-mock-mvc module:
<dependency>
<groupId>com.jayway.restassured</groupId>
<artifactId>spring-mock-mvc</artifactId>
<version>${rest-assured.version}</version>
<scope>test</scope>
</dependency>
Or gradle:
testCompile "com.jayway.restassured:spring-mock-mvc:${rest-assured.version}"
This happened to me when using restassured with Maven (Surprisingly, Gradle did not give me this problem, it handled it well unlike Maven).
For me, it was a dependency conflict. I had Apache Phoenix as dependency in my pom.xml
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix</artifactId>
<version>4.13.2-cdh5.11.2</version>
This Apache Phoenix jar depends on httpclient version 4.0.1 jar which overrides the version which my restassured jar depends on (which is httpclient version 4.3.5) . Maven had excluded this later version (4.5.3) by default.
To solve this, I added exclusion for the older version under my Apache Phoenix pom section which looked like this:
<dependency>
<groupId>org.apache.phoenix</groupId>
<artifactId>phoenix-core</artifactId>
<version>4.13.2-cdh5.11.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
That way the version of httpclient in my restassured jar superceded and everything worked fine.

Categories

Resources