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>
Related
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
This is my Test Class:
public class CompanionDevicesRestServiceTest {
public static ComDevicesRestService comDevicesRestService;
public static IComDevices cdevicesService;
public static ComDevices cdevicesRequest;
#BeforeClass
public static void init(){
cdevicesService = new StubComDevicesService();
comDevicesRestService = new ComDevicesRestService(cdevicesService);
cdevicesRequest = mock(ComDevices.class);
}
#Test
public void testPostCdevices() throws JsonProcessingException{
WireMock.stubFor(WireMock.post(WireMock.urlEqualTo("/cdevices"))
.withHeader("Accept", WireMock.equalTo("application/json"))
.willReturn(WireMock.aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("Some content")));
}
}
I am getting the following error :
com.github.tomakehurst.wiremock.client.VerificationException: Expected status 201 for http://localhost:8080/__admin/mappings/new but was 404
at com.github.tomakehurst.wiremock.client.HttpAdminClient.postJsonAssertOkAndReturnBody(HttpAdminClient.java:156)
at com.github.tomakehurst.wiremock.client.HttpAdminClient.addStubMapping(HttpAdminClient.java:65)
at com.github.tomakehurst.wiremock.client.WireMock.register(WireMock.java:138)
at com.github.tomakehurst.wiremock.client.WireMock.register(WireMock.java:134)
at com.github.tomakehurst.wiremock.client.WireMock.givenThat(WireMock.java:65)
at com.github.tomakehurst.wiremock.client.WireMock.stubFor(WireMock.java:69)
at com.charter.cdevices.rest.CompanionDevicesRestServiceTest.testPostCdevices(CompanionDevicesRestServiceTest.java:33)
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: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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
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:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
For this example, I suppose the wiremock was started externally,right? So you should add the configure for with the host and the port:
configureFor("localhost", 8080);
You should use the WireMock rule
#Rule
public WireMockRule wireMockRule = new WireMockRule();
and after that you could use it to create your stubs
wireMockRule.stubFor(WireMock.post(WireMock.urlEqualTo("/cdevices"))
.withHeader("Accept", WireMock.equalTo("application/json"))
.willReturn(WireMock.aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("Some content")));
ClassRule annotation can be also used:
public class CompanionDevicesRestServiceTest {
public static ComDevicesRestService comDevicesRestService;
public static IComDevices cdevicesService;
public static ComDevices cdevicesRequest;
#ClassRule
public static WireMockClassRule wireMockRule = new WireMockClassRule(wireMockConfig()
.containerThreads(20)
.port(8080)
);
#BeforeClass
public static void init(){
cdevicesService = new StubComDevicesService();
comDevicesRestService = new ComDevicesRestService(cdevicesService);
cdevicesRequest = mock(ComDevices.class);
}
#Test
public void testPostCdevices() throws JsonProcessingException{
wireMockRule.stubFor(WireMock.post(WireMock.urlEqualTo("/cdevices"))
.withHeader("Accept", WireMock.equalTo("application/json"))
.willReturn(WireMock.aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("Some content")));
}
}
and call stubFor method on the class rule object.
As per the WireMock documentation, we have three major approaches: JUnit 5.x, Junit4.x, and standalone.
My recommendation would be simple: double-check which approach is yours and proceed to the documented recommendation, but...
It never worked for me. In order to fix the issue discussed here, I did the following:
Added a #Rule to the very beginning of the test. I will share the entire class declaration down here, including the runner and a short SSL witchery to run this stuff with PowerMockRunner:
#RunWith(PowerMockRunner.class)
#PowerMockIgnore("javax.net.ssl.*")
public class StartingOddsChangesProviderIntegrationTest {
#Rule public WireMockRule wireMockRule = new WireMockRule();
(...)
You DO NOT need to do instantiate a WireMockServer, neither need you to add a server.start()/stop() line now that the #Rule annotation is there.
Finally, the WireMock depedency entry in the corresponding pom.xml file is as follows:
<dependency>
<groupId>com.github.tomakehurst</groupId>
<artifactId>wiremock-standalone</artifactId>
<version>2.27.0</version>
<scope>test</scope>
</dependency>
I've tried the wiremock-jre8 artifact as well, but I ended up having the same error, so I'm pushing ahead with the wiremock-standalone.
I am running junit written in Custom JSR 303 Validation using ConstraintValidator. Something like this example
My Validation test class:
public class ProductV2ValidationTest {
private static Validator validator;
#Before
public void setUp() throws ExternalApiException {
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
validator = validatorFactory.getValidator();
}
#Test
public void ValidatorTest() {
try {
ProductV2 productV2 = getObjectMapper().readValue(this.getClass().getResourceAsStream("/json/productV2Valid.json"), ProductV2.class);
Set<ConstraintViolation<ProductV2>> constraintViolations = validator.validate(productV2);
for(ConstraintViolation<ProductV2> constraintViolation : constraintViolations){
String message = constraintViolation.getMessage();
System.out.println(message);
}
assertEquals(0,constraintViolations.size());
} catch (IOException e) {
e.printStackTrace();
assertTrue(false);
}
}
}
FYI, My validators are in some another maven project(jar),and test are written in another maven project(war).
I am getting this error:
javax.validation.ValidationException: HV000063: Unable to instantiate class com.xyz.gep.itemwrapper.external.entities.validator.NumberOfObjectsValidater.
at org.hibernate.validator.internal.util.privilegedactions.NewInstance.run(NewInstance.java:54)
at org.hibernate.validator.internal.util.ReflectionHelper.run(ReflectionHelper.java:658)
at org.hibernate.validator.internal.util.ReflectionHelper.newInstance(ReflectionHelper.java:206)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorFactoryImpl.getInstance(ConstraintValidatorFactoryImpl.java:34)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.createAndInitializeValidator(ConstraintValidatorManager.java:141)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.getInitializedValidator(ConstraintValidatorManager.java:101)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:125)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:91)
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:85)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:478)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:424)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:388)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:340)
at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:158)
at com.rakuten.gep.itemwrapper.external.entities.validator.ProductV2ValidationTest.ValidatorTest(ProductV2ValidationTest.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.lang.reflect.Method.invoke(Method.java:606)
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.lang.IllegalAccessException: Class org.hibernate.validator.internal.util.privilegedactions.NewInstance can not access a member of class com.rakuten.gep.itemwrapper.external.entities.validator.NumberOfObjectsValidater with modifiers ""
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:109)
at java.lang.Class.newInstance(Class.java:368)
at org.hibernate.validator.internal.util.privilegedactions.NewInstance.run(NewInstance.java:48)
at org.hibernate.validator.internal.util.ReflectionHelper.run(ReflectionHelper.java:658)
at org.hibernate.validator.internal.util.ReflectionHelper.newInstance(ReflectionHelper.java:206)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorFactoryImpl.getInstance(ConstraintValidatorFactoryImpl.java:34)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.createAndInitializeValidator(ConstraintValidatorManager.java:141)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager.getInitializedValidator(ConstraintValidatorManager.java:101)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:125)
at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:91)
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:85)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:478)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:424)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:388)
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:340)
at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:158)
at com.rakuten.gep.itemwrapper.external.entities.validator.ProductV2ValidationTest.ValidatorTest(ProductV2ValidationTest.java:36)
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 mockit.integration.junit4.internal.BlockJUnit4ClassRunnerDecorator.executeTest(BlockJUnit4ClassRunnerDecorator.java:126)
at mockit.integration.junit4.internal.BlockJUnit4ClassRunnerDecorator.invokeExplosively(BlockJUnit4ClassRunnerDecorator.java:104)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java)
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: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)
... 6 more
I tried adding
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>javax.el</artifactId>
<version>2.2.4</version>
</dependency>
But no help .
I am using this dependancy:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.2.Final</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
The Problem is that the hibernate validator cannot create a new instance of com.rakuten.gep.itemwrapper.external.entities.validator.NumberOfObjectsValidater because it does not have a public default constructor.
You should be able to reproduce the problem be executing the following code:
public static void test() throws InstantiationException, IllegalAccessException {
try {
com.rakuten.gep.itemwrapper.external.entities.validator.NumberOfObjectsValidater.class.newInstance();
}
catch ( InstantiationException e ) {
throw e;
}
catch ( IllegalAccessException e ) {
throw e;
}
catch ( RuntimeException e ) {
throw e;
}
}
The solution would be to add public modifier to the constructor of NumberOfObjectsValidater
add "public" to class declaration
your code:
class NumberOfObjectsValidater implements ConstraintValidator<IpAddress, String>{
}
right code:
public class NumberOfObjectsValidater implements ConstraintValidator<IpAddress, String>{
}
I'm trying to configure mail in Spring and keep getting a null pointer exception. My suspicion is that it can't find the "mailSender" bean but I could be way off. My configuration is as follows:
web.xml
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>logVerbosityLevel</param-name>
<param-value>ERROR</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
servlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<beans:bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<beans:property name="host" value="mail.company.com"/>
</beans:bean>
</beans:beans>
SendMailTest.java
package company.test;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.activation.CommandMap;
import javax.activation.MailcapCommandMap;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mock.web.MockServletContext;
import company.AppListener;
public class SendMailTest {
private static final Logger logger = AppListener.getLogger();
#Mock
private ServletContextEvent mockServletContextEvent;
private final Map<String, Object> map = new HashMap<String, Object>();
#Mock
private ServletContext mockServletContext;
#Before
public void setUp() {
System.setProperty("java.net.preferIPv4Stack" , "true");
initMocks(this);
map.clear();
when(mockServletContextEvent.getServletContext()).thenReturn(mockServletContext);
Mockito.doAnswer(new Answer<Object>() {
public Object answer(final InvocationOnMock invocation)
throws Throwable {
final String key = (String) invocation.getArguments()[0];
final Object value = invocation.getArguments()[1];
return map.put(key, value);
}
}).when(mockServletContext).setAttribute(Mockito.anyString(), Mockito.anyObject());
Mockito.doAnswer(new Answer<Object>() {
public Object answer(final InvocationOnMock invocation)
throws Throwable {
final Object value = invocation.getArguments()[0];
return map.remove(value);
}
}).when(mockServletContext).removeAttribute(Mockito.anyString());
}
#Autowired
private MailSender mailSender;
#Test
public void testSendSimpleEmaill() {
SimpleMailMessage message = new SimpleMailMessage();
String name = "John Doe";
message.setFrom("john.doe#company.com");
message.setTo("jane.doe#company2.com");
message.setSubject("Test Email from Spring");
message.setText("Will email ever work?");
try {
mailSender.send(message);
}
catch (Exception e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
}
}
Stack Trace
java.lang.NullPointerException
at company.test.SendMailTest.testSendSimpleEmaill(SendMailTest.java:85)
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:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
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)
null
When you're running the test with JUnit, Spring isn't loaded at all, so the autowired fields aren't being set. To run spring in a test, look into the SpringJUnit4ClassRunner.
You can also create your own instance of JavaMailSenderImpl within the setUp method and assign it to mailSender
yu need to put the configurations in your test class, also you whould like to copy your context file to the root of your test class (just file resolution, when the spring runners starts needs to load your context file)..your test class should look like this...
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = { "applicationContext.xml" })
#WebAppConfiguration
public class FacadeTest {
private String phoneNumber = "111111115";
#Autowired
private BussinesDelegate bussinesDelegate;
#Test
public void runTest(){
this.fullTest(phoneNumber, "aaaaa");
}
public void fullTest(String phoneNumber, String answer){
try {
bmoaBussinesDelegate.processMessage("127.0.0.1", phoneNumber, "camicase" + System.currentTimeMillis());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
and dont forget to check your dependencies!
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- Testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
The cool thing about spring, its that its IOC container can probide the same behavior as a full Java EE compliant server without needing a server, and basically what the runner does is to load the context manually, the same way you could do ir in a standole app with spring ;)
I have this class JerseySpringSuiteTest.java:
#RunWith(Suite.class)
#Suite.SuiteClasses({ ProductTest.class })
public class JerseySpringSuiteTest {
public static JerseyTest jerseyTest;
#BeforeClass
public static void init() {
jerseyTest = new JerseyTest(new WebAppDescriptor.Builder("com.product.resource")
.contextParam("contextConfigLocation", "classpath:applicationContext.xml").servletClass(SpringServlet.class)
.contextListenerClass(ContextLoaderListener.class).requestListenerClass(RequestContextListener.class).build()) {
};
}
}
and ProductTest.java:
public class ProductTest{
#Before
public void before() throws Exception {
JerseySpringSuiteTest.jerseyTest.setUp();
ExecutorService productExecutorService = ContextLoaderListener.getCurrentWebApplicationContext().getBean(
"productExecutorService", ExecutorService.class);
Assert.assertNotNull(productExecutorService);
}
#Test
public void testNoAction() {
WebResource webResource = JerseySpringSuiteTest.jerseyTest.resource();
String responseMsg = webResource.path("product/").get(String.class);
Assert.assertEquals("No Action Specified", responseMsg);
}
#Test
public void testGetProducts() throws URISyntaxException {
WebResource webResource = JerseySpringSuiteTest.jerseyTest.resource().path(
"Products/rest/product/getProducts/1/productName/01-01-2013/");
ClientResponse response = webResource.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class);
Assert.assertEquals(200, response.getStatus());
}
}
and Product.java:
#Component
#Path("/product")
public class Product{
#Autowired
private ProductService productService;
#GET
#Produces(MediaType.APPLICATION_JSON)
public Object noAction() {
return "No Action Specified";
}
#GET
#Path("/getProducts/{companyID}/{companyName}/{date}")
#Produces(MediaType.APPLICATION_JSON)
public Object getProducts(#PathParam("companyID") final int companyID,
#PathParam("date") final String date, #PathParam("companyName") final String companyName)
throws IOException {
return productService.getProducts(companyID, companyName, date);
}
}
When I execute it I see:
java.lang.AssertionError: expected:<200> but was:<404>
at org.junit.Assert.fail(Assert.java:88)
at org.junit.Assert.failNotEquals(Assert.java:743)
at org.junit.Assert.assertEquals(Assert.java:118)
at org.junit.Assert.assertEquals(Assert.java:555)
at org.junit.Assert.assertEquals(Assert.java:542)
at com.product.resource.MonitoringEngineResourceTest.testGetProducts(ProductTest.java:27)
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:601)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
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.junit.runners.Suite.runChild(Suite.java:127)
at org.junit.runners.Suite.runChild(Suite.java:26)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
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)
I am able to get data when I ping URL in browser.
Could some one please help me to get response status as 200 and JSON object?
NOTE: I am using jersey 1.17.1 version and grizzly2 container.
According to your noAction unit test, the correct URL seems to be:
webResource.path("product/")
This is also confirmed by your actual service class:
#Path("/product")
public class Product {
//...
}
This means that you need to change your other test to use the same path.
Also, it is companyName, not productName as per your service class.
#Test
public void testGetProducts() throws URISyntaxException {
WebResource webResource = JerseySpringSuiteTest.jerseyTest.resource();
ClientResponse response =
webResource.path("product/getProducts/1/companyName/01-01-2013/")
.accept(MediaType.APPLICATION_JSON)
.get(ClientResponse.class);
Assert.assertEquals(200, response.getStatus());
}
One possible reason that it works in a browser is that your server (Tomcat, Jetty, etc.) is configured to add the common URL prefix Products/rest to all paths. This server is not in the picture when you execute unit tests.