I'm new to junit and TDD.
I've just made my first test case.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:spring-beans/spring-cms-root.xml"})
public class MemberServiceImplTest {
#Autowired
MemberService memberService;
#Test
public void testGetMemberById() {
Member member = memberService.getMemberById("testid");
assertTrue(member != null);
}
#Test
public void testGetMemberBySeq() {
Member member = memberService.getMemberBySeq(1);
assertTrue(member != null);
}
}
But this Test Class gave me this error below upon running junit test.
java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.tource.cms.member.MemberService.getMemberById
at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:672)
at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:507)
at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:500)
at org.apache.ibatis.binding.MapperMethod.setupCommandType(MapperMethod.java:240)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:71)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:39)
at $Proxy18.getMemberById(Unknown Source)
at com.tource.cms.member.MemberServiceImplTest.testGetMemberById(MemberServiceImplTest.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
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.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
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)
So I changed my test class little as below.
public class MemberServiceImplTest {
MemberService memberService;
public MemberServiceImplTest() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-beans/spring-cms-root.xml");
memberService = ctx.getBean("memberServiceImpl", MemberServiceImpl.class);
}
#Test
public void testGetMemberById() {
Member member = memberService.getMemberById("testid");
assertTrue(member != null);
}
#Test
public void testGetMemberBySeq() {
Member member = memberService.getMemberBySeq(1);
assertTrue(member != null);
}
}
And this works well. anyone has idea why it works or not?
I don't have any idea about difference between two classes.
Either your mybatis mapping/config files are not being loaded, or your bean is not being auto-wired properly. In the broken example, try adding #Qualifier("memberServiceImpl") to your memberService declaration just below #Autowired.
FYI since you say you're new to unit testing, instead of assertTrue(member != null), you should assertNotNull(member). In the event that your assert fails, this will produce a slightly better error message.
Related
I'm using Spring 4.3.8.RELEASE, JUnit 4.12 ,and Mockito 1.10.18. I'm trying to test whether my "publishEvent" method is called from below ...
#Service
#Transactional
public class MyObjectServiceImpl implements MyObjectService, ApplicationEventPublisherAware
{
private ApplicationEventPublisher publisher;
#Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher)
{
this.publisher = publisher;
}
...
public void myMethod(MyObject obj) {
...
publisher.publishEvent(new ThirdPartyUpdateUserEvent(userId));
publisher.publishEvent(new ThirdPartyUpdateObjectEvent(objectId));
and then in my JUnit test I have
#Before
public final void setup()
{
eventPublisher = Mockito.mock(ApplicationEventPublisher.class);
((ApplicationEventPublisherAware) myObjectService).setApplicationEventPublisher(eventPublisher);
((ApplicationEventPublisherAware) userService).setApplicationEventPublisher(eventPublisher);
} // setup
#Test
...
// Verify first call
final ArgumentCaptor<ThirdPartyUpdateUserEvent> argument2 = ArgumentCaptor.forClass(ThirdPartyUpdateUserEvent.class);
Mockito.verify(eventPublisher, Mockito.times(2)).publishEvent(argument2.capture());
Assert.assertEquals("Failed to call method with proper argument.", userId, argument2.getValue().getUserId());
// Verify second call
final ArgumentCaptor<ThirdPartyUpdateMyObjectEvent> argument = ArgumentCaptor.forClass(ThirdPartyUpdateMyObjectEvent.class);
Mockito.verify(eventPublisher, Mockito.times(2)).publishEvent(argument.capture());
Assert.assertEquals("Failed to call method with proper argument.", objectId, argument.getValue().getObjectId());
Through debugging, I can see that each of the "publishEvent" methods is called exactly once, yet when I go to verify the calls I get the error for the first "verify" line in my #Test
java.lang.ClassCastException: org.mainco.subco.ThirdPartyItem.domain.ThirdPartyUpdateMyObjectEvent cannot be cast to org.mainco.subco.ThirdPartyItem.domain.ThirdPartyUpdateUserEvent
at com.follett.fdr.lycea.lms.MyObject.test.service.MyObjectServiceDWRTest.testArchiveMyObject(MyObjectServiceDWRTest.java:1234)
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.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
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.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)
What's the right way to verify two consecutive calls to my mocked publish service?
Instead of creating an ArgumentCaptor for ThirdPartyUpdateUserEvent and
ThirdPartyUpdateMyObjectEvent, why not create one captor for Object:
final ArgumentCaptor<Object> argumentsCaptor = ArgumentCaptor.forClass(Object.class);
Or better yet, whatever common interface ThirdPartyUpdateUserEvent and ThirdPartyUpdateMyObjectEvent implement (ThirdPartyUpdateEvent?)
Now you can do this:
Mockito.verify(eventPublisher, Mockito.times(2)).publishEvent(argumentsCaptor.capture());
List<Object> arguments = argumentsCaptor.getAllValues();
assertTrue(arguments.get(0) instanceof ThirdPartyUpdateUserEvent);
assertTrue(arguments.get(1) instanceof ThirdPartyUpdateMyObjectEvent);
And test those arguments for whatever other conditions you need.
I'm trying to create a very basic unit test for a spring mvc rest controller using the MockMvcBuilders.standaloneSetup method. I keep getting a 404 error. Below I list my Test application context, my test class, and my controller and the full stack trace. Any guidance is appreciated.
#Configuration
public class TestContext
{
#Bean
public Service service()
{
return mock(Service.class);
}
}
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes={TestContext.class})
#WebAppConfiguration
public class TestUsingWebAppContextSetUp
{
private MockMvc mockMvc;
#Autowired
private Service service;
#Before
public void setUp()
{
mockMvc = MockMvcBuilders.standaloneSetup(MyController.class)
.build();
}
#Test
public void test() throws Exception
{
mockMvc.perform(get("/search?phoneNumber=5551112222"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE));
}
}
public class MyController
{
#Autowired
private Service service;
#RequestMapping("/search")
public List<SearchResult> search(#RequestParam(value="phoneNumber") String phoneNumber)
{
System.out.println("search called");
Search search = new Search();
search.setPhoneNumber(phoneNumber);
return service.search(search);
}
}
java.lang.AssertionError: Status expected:<200> but was:<404> at
org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at
org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at
org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:653)
at
org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:152)
at
com.mycompany.TestUsingWebAppContextSetUp.test(TestUsingWebAppContextSetUp.java:41)
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.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:217)
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) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
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: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)
The javadoc of MockMvcBuilders.standaloneSetup states
Build a MockMvc by registering one or more #Controller's instances and
configuring Spring MVC infrastructure programmatically. This allows
full control over the instantiation and initialization of controllers,
and their dependencies, similar to plain unit tests while also making
it possible to test one controller at a time.
So you would use it as
mockMvc = MockMvcBuilders.standaloneSetup(new MyController()).build();
registering an actual instance. If you need this to be a Spring managed instance (which you probably do considering it has an #Autowired field), you'd have to get it from the ApplicationContext.
I’m using Spring 3.2.11.RELEASe, JUnit 4.12, and Mockito 1.10.18. In my JUnit test, how do I create a spy (not a mock, a spy) of an #Autowired spring service? Here’s how the service is declared …
#Service("orderService")
public class OrderServiceImpl implements OrderService, InitializingBean
{
and here is how my JUnit test is set up …
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "classpath:test-context.xml" })
public class ProcessPDWorkerTest extends AbstractWorkerTest
{
…
#Autowired
protected OrderService m_orderSvc;
with
final OrderService orderSvcSpy = Mockito.spy(getTargetObject(m_orderSvc));
…
ReflectionTestUtils.setField(workerObj, "m_orderSvc", orderSvcSpy);
where I have …
protected static <T> T getTargetObject(Object proxy)
{
if ((AopUtils.isJdkDynamicProxy(proxy)))
{
try
{
return (T) getTargetObject(((Advised) proxy).getTargetSource().getTarget());
}
catch (Exception e)
{
throw new RuntimeException("Failed to unproxy target.", e);
}
}
return (T) proxy;
}
but I get the following exception on the line “Mockito.spy(getTargetObject(m_orderSvc))”:
java.lang.ClassCastException: org.mainco.subco.myproject.service.OrderServiceImpl cannot be cast to java.lang.Class
at org.mainco.subco.test.worker.AbstractWorkerTest.createMockOrders(AbstractWorkerTest.java:146)
at org.mainco.subco.orders.ProcessPDWorkerTest.mockTrainingAssignmentAndOrder(ProcessPDWorkerTest.java:1117)
at org.mainco.subco.orders.ProcessPDWorkerTest.testCreateTrainingSessionWTrainer(ProcessPDWorkerTest.java:297)
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: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.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
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: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)
Alternatively, you can try to change only this line:
final OrderService orderSvcSpy = Mockito.spy((OrderService)getTargetObject(m_orderSvc));
…
This should work. Mockito.spy() is an overloaded static method and compiler choses Mockito.spy(Class) at compile time.
Works for me:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration({ "classpath:test-context.xml" })
public class ProcessPDWorkerTest extends AbstractWorkerTest {
…
#Spy
#Autowired
protected OrderService m_orderSvc;
#Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(workerObj, "m_orderSvc", m_orderSvc);
}
I am unit testing the following Spring MVC controller method:
#RequestMapping(value = "/advertisement/family/edit/{advertisementId}", method = RequestMethod.GET, produces = "text/html")
#AdvertisementExistsAndBelongsToMemberCheck
public String editFamilyAdvertisementForm(#ModelAttribute FamilyAdvertisementInfo familyAdvertisementInfo, #PathVariable long advertisementId, Model model, #CurrentMember Member member) {
FamilyAdvertisement advertisement = advertisementService.findFamilyAdvertisement(advertisementId);
familyAdvertisementInfo.setFamilyAdvertisement(advertisement);
populateFamilyAdvertisementModel(model, familyAdvertisementInfo, member);
return "advertisement/family/edit";
}
The custom annotation (#AdvertisementExistsAndBelongsToMemberCheck) above basically is advised by an aspect as follows:
before(long advertisementId, Member member) : advertisementBelongsToMemberControllerCheck(advertisementId, member) {
if (!advertisementService.advertisementExistsAndBelongsToMember(advertisementId, member)) {
throw new AccessDeniedException("Advertisement does not belong to member!");
}
}
If an AccessDeniedException is thrown, then the following controller advice exception handler kicks in:
#ExceptionHandler(AccessDeniedException.class)
#ResponseStatus(value = HttpStatus.FORBIDDEN)
public String accessDeniedException(AccessDeniedException e) {
return "error/403";
}
Now, here is how I am trying to test the above controller method:
#ContextConfiguration
#WebAppConfiguration
#RunWith(SpringJUnit4ClassRunner.class)
public class AdvertisementControllerTest {
#Autowired
private WebApplicationContext ctx;
private MockMvc mockMvc;
#Autowired
private AdvertisementService advertisementService;
#Before
public void setup() {
mockMvc = webAppContextSetup(ctx).build();
when(advertisementService.advertisementExistsAndBelongsToMember(eq(111), any(Member.class))).thenReturn(Boolean.FALSE);
when(advertisementService.advertisementExistsAndBelongsToMember(eq(222), any(Member.class))).thenReturn(Boolean.TRUE);
}
#Test
public void shouldAllow() throws Exception {
mockMvc.perform(get("/advertisement/family/edit/222"))//
.andDo(print())//
.andExpect(status().isOk());
}
#Configuration
#EnableSpringConfigured
static class testConfiguration {
#Bean
public AdvertisementController advertisementController() {
return new AdvertisementController();
}
#Bean
public InternalResourceViewResolver getInternalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/pages/");
resolver.setSuffix(".jsp");
return resolver;
}
#Bean
public AdvertisementService advertisementService() {
return mock(AdvertisementService.class);
}
}
}
The test systematically fails with the following stacktrace:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.security.access.AccessDeniedException: Advertisement does not belong to member!
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:948)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:66)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:168)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:136)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:134)
at com.bignibou.tests.controller.advertisement.AdvertisementControllerTest.shouldAllow(AdvertisementControllerTest.java:64)
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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
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.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
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: org.springframework.security.access.AccessDeniedException: Advertisement does not belong to member!
at com.bignibou.aop.AdvertisementExistsAndBelongsToMemberCheckAspect.ajc$before$com_bignibou_aop_AdvertisementExistsAndBelongsToMemberCheckAspect$2$3edd453b(AdvertisementExistsAndBelongsToMemberCheckAspect.aj:34)
at com.bignibou.controller.advertisement.AdvertisementController.editFamilyAdvertisementForm(AdvertisementController.java:56)
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.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:176)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:440)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:428)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
... 38 more
I am not sure what I am getting wrong with Mockito...
Note that I did specify /222 in the path, indicating that my mock should return true in the aspect and allow the controller method to proceed. However, this is not the case.
Can anyone please help?
Is the aspect injected with the same mocked instance of AdvertisementService?
The issue is that the type of the argument was a long and I passed an int.
Changing to:
when(advertisementService.advertisementExistsAndBelongsToMember(eq(222L), any(Member.class))).thenReturn(Boolean.TRUE);
and:
#Test
public void shouldAllow() throws Exception {
mockMvc.perform(get("/advertisement/family/edit/{advertisementId}", 222L))//
.andDo(print())//
.andExpect(status().isOk());
}
sorted the issue.
In my first Spring Roo project, I noticed a strange behaviour while testing the auto-generated entity tests (entity jpa --class ~.xyz --testAutomatically):
In every generated xyzIntegrationTest_Roo_IntegrationTest.aj file, the testRemove() test, such as
#Test
public void xyzImplIntegrationTest.testRemove() {
xyzImpl obj = dod.getRandomxyzImpl();
Assert.assertNotNull("Data on demand for 'xyzImpl' failed to initialize correctly", obj);
Long id = obj.getId();
Assert.assertNotNull("Data on demand for 'xyzImpl' failed to provide an identifier", id);
obj = xyzImpl.findxyzImpl(id);
obj.remove();
obj.flush();
// this is the assertion that does not hold
Assert.assertNull("Failed to remove 'xyzImpl' with identifier '" + id + "'", xyzImpl.findxyzImpl(id));
}
, fail in the JUnit test queue after I add the following artificial test and test it before the others.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.junit.Assert;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
#RunWith(JUnit4.class)
public class DummyTest {
#Test
public void ArtificialTest()
{
ApplicationContext ac =
new ClassPathXmlApplicationContext("classpath*:META-INF/spring/applicationContext.xml");
// the same problem occurs for
// new FileSystemXmlApplicationContext("src/main/resources/META-INF/spring/applicationContext.xml");
Assert.assertTrue(true);
}
}
Note that all tests run without errors if executed independently and that I have not modified the applicationContext.xml provided by Spring Roo at all.
My questions are now:
Is this a known bug with an existing workaround or am I missing something important?
Is there another way to get the application context for an individual written test?
Below you find the corresponding failure trace:
java.lang.AssertionError: Failed to remove 'xyzImpl' with identifier '1'
at org.junit.Assert.fail(Assert.java:93)
at org.junit.Assert.assertTrue(Assert.java:43)
at org.junit.Assert.assertNull(Assert.java:551)
at xyzImplIntegrationTest_Roo_IntegrationTest.ajc$interMethod$xyzImplIntegrationTest_Roo_IntegrationTest$xyzImplIntegrationTest$testRemove(xyzImplIntegrationTest_Roo_IntegrationTest.aj:118)
at xyzImplIntegrationTest.testRemove(xyzImplIntegrationTest.java:1)
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:45)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
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)