Spring MVC Unit Test - how to use hamcrest matcher - spring-mvc

I'm trying to write a simple test case for an MVC controller method.
I want to test the view name contains a string.
I think I need this version of the name matcher:
public ResultMatcher name(org.hamcrest.Matcher<? super String> matcher)
Taken from here:
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/test/web/servlet/result/ViewResultMatchers.html#name-org.hamcrest.Matcher-
But how do I use it? I can't work out the right syntax...
(syntax error on the Matchers.contains("web_tmpl") part of this expression:
this.mockMvc.perform(MockMvcRequestBuilders.get("/content/2"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.view().name(Matchers.contains("web_tmpl")))
;

You should add a static import for
import static org.hamcrest.Matchers.containsString;
and use
.andExpect(view().name(containsString("web_tmpl")))
if you're using maven the dependency is
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>

Related

Spring 4 AOP #Aspect isn't triggering for #RestController

I have created an Aspect which performs a basic id comparison to ensure that a user belongs to a the same group that created the entity being requested. I have had success attaching my aspect to #Service methods, but it doesn't make sense on the service layer, and I need it to be attached to #RestController methods instead. When I attempt to do this, everything seems good, but my Aspect never triggers, and the logs are silent.
pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
spring context
<context:annotation-config/>
<context:component-scan base-package="my.pkg"/>
<aop:aspectj-autoproxy/>
<aop:config proxy-target-class="true"/>
Aspect
#Aspect
#Component
public class MyAspect {
#Pointcut("within(#org.springframework.stereotype.Controller *)")
public void controller() {}
#Pointcut("within(#org.springframework.web.bind.annotation.RestController *)")
public void restController() {}
#Pointcut("args(java.security.Principal,..)")
public void principalArgPointcut() {}
#Around("(controller() || restController()) && principalArgPointcut()")
public Object validate(ProceedingJoinPoint point) throws Throwable {
doValidationBefore();
Object result = point.proceed();
doValidationAfter();
return result;
}
}
where "doValidationBefore()" and "doValidationAfter()" will throw an exception if validation fails.
And finally, my RestController
#RestController
#RequestMapping("/my-path")
public class MyController {
#RequestMapping(value = "/{entityId}", method = RequestMethod.GET)
public #ResponseBody
ResponseEntity<MyEntity> getEntityDetails(Principal principal, #PathVariable("entityId") Long entityId) {
return new ResponseEntity(HttpStatus.OK);
}
}
Some things to note:
This exact aspect works when I change the execution pattern to match services and place it in my service package.
The Aspect and the RestController are in the same context
I use IDEA IDE, and when I use the "navigate to advised methods" icon on the Aspect, the method I'm testing IS listed in the list of methods.
None of the methods listed in "navigate to advised methods" are working
Things I have tried:
I added 3 libraries to my pom.xml: org.aspectj:aspectjrt:1.8.6,
org.aspectj:aspectjtools:1.8.6, cglib:cglib:2.2.2. None of these made
any difference.
I tried defining my Aspect and PointCuts directly in the context xml and removing the annotations, no difference.
I have tried setting my execution pattern to apply to ALL methods, and it still did not trigger.
I tried adding an interface for my RestController, no change.
I would love some help here, as I've been trying to solve this for quite some time now. I know it must be possible.
As it turns out, my Aspect and my Controllers were NOT, in fact, in the same context.
While I believed my Controllers to be included in the context scanning of my web-context.xml, they were actually being scanned in WEB-INF/servlet-context.xml
Once I moved my Aspect configuration to WEB-INF/servlet-context.xml, my Aspect began to trigger as expected.
Thanks for all those who contemplated my problem.
Figure out for sure where your service is being configured in spring. If you have I there is an icon that you can click to navigate to the spring bean config. Then ensure that the aspect is configured in the same file.
If they are definitely defined in the same file, look next that the aop pointcut advice matches the method on which you're expecting it to fire. Again, Idea has an icon next to the pointcut that will navigate to matching methods.

Sylius how to override the CoreBundle Checkout process

I'm working on a project and I'd like to ask for a clean/best way to override the steps in the
Sylius\Bundle\CoreBundle\Checkout\CheckoutProcessScenario
I'd like to preserve the custom mechanics of the whole process just add a custom step at the end and remove the finalize step.
$builder
->add('security', 'sylius_checkout_security')
->add('addressing', 'sylius_checkout_addressing')
->add('shipping', 'sylius_checkout_shipping')
->add('finalize', 'sylius_checkout_finalize')
->add('payment', 'sylius_checkout_payment')
->add('purchase', 'sylius_checkout_purchase')
;
What's the best form of doing so? If it's extending the bundle and overwriting it I'd like some help with that of at least some information to point me in the right direction - currently I'm not getting any results on my own.
I've read the docs on the bundle itself but it doesn't explain how to override the built in process.
I've also read the symfony cookbook on extending resources:
http://symfony.com/doc/2.0/cookbook/bundles/inheritance.html#overriding-resources-templates-routing-translations-validation-etc
and:
http://symfony.com/doc/current/cookbook/bundles/override.html
If anyone has some experience on the topic and would like to share thier insights I'd be very gratefull. Thanks in advance.
You could change the service class to a custom one.
You can overwrite the parameter sylius.checkout_scenario.class.
app/config/config.yml:
<parameter key="sylius.checkout_scenario.class">
Your\Class
</parameter>
I've done it a bit different but still the point was good :)
What I've done is use the service compiler to override it with my own class and override the original file. The basics are explained here:
http://symfony.com/doc/current/cookbook/bundles/override.html
in the Services & Configuration section :)
Then I just had to include the compiler pass
// src/Acme/ShopBundle/AcmeShopBundle.php
namespace Acme\ShopBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Acme\ShopBundle\DependencyInjection\Compiler\CustomCompilerPass;
class AcmeMailerBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new CustomCompilerPass());
}
}
Inside the compiler pass I just extended the base file and overwrote the function I needed. Droppin it by in case anyone needs to pointed in the right direction.

Change name of Resteasy generated <collection> element to something else?

<collection>
<Car>
<Car>
<Car>
</collection>
I would like to change the name of the tag to
I have no idea what I'm using--it's just Jboss 7.1.1 and a standard multimodule EAR maven setup. I should have RESTEasy included, with whatever JAXB provider they use.
#XmlElementWrapper annotation I have access to, but it does not work when I annotate the JAXRS service method "getCars". It has no effect on the xml output.
#Wrapped(element="cars") doesn't work b/c I can not seem to import the RESTEasy jax-rs jar. I added it into my pom.xml but it's not being picked up.
1) no idea if "jboss having RESTEasy included" means that I shouldn't even need to worry about importing another library just so that I can use the #Wrapped annotation.
2) Can I get by with the #XmlElementWrapper annotation for my purposes?
#GET
#Produces({MediaType.APPLICATION_XML})
#Path("/")
#XmlElementWrapper(name="cars")//I have access to this annotation but nothing happens
#Wrapped(element="cars")//eclipse doesn't know what this annotation means
public List<car> getCars();
You should be able to accomplish this by using the #Wrapped annotation.
To get this annotation into your project, try to add this artifact to your pom.xml:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>${resteasy.version}</version>
</dependency>
Another option is to create your own wrapper class:
#XmlRootElement(name="cars")
public class CarCollection {
#XmlElement(name="car")
private List<Car> articles = new ArrayList<Car>();
}
#GET
#Produces({MediaType.APPLICATION_XML})
#Path("/")
public CarCollection getCars();
Using just the #XmlElementWrapper annotation won't work.

Specify run time parameter dependency in Unity

I have a class which needs a string as a parameter in its constructor but this parameter will be decided by the calling code. At the same point of time, the life time of this class has to be tied to per HTTP request. So, I created a custom PerWebRequestTimelineManager and used that for my target type in the config file. But since the string in the constructor has to be dynamically determined, I cannot use the ConstructorInjection via the config file. I can use an abstract factory to solve the problem of dynamic dependency, but I am not sure about the implementation: Can you check the code below and validate the approach. Specifically the RegisterType and Resolve calls seem a bit out of place though the successive Resolve calls across the application will be able to retrieve the same instance.:
public class PerformanceTracerFactory : IPerformanceTracerFactory
{
private readonly IPerformanceTracer tracer;
public IPerformanceTracer CreateInstance(string operationTitle)
{
_container.RegisterType<IPerformanceTracer, PerformanceTracer>(new InjectionConstructor(operationTitle));
return _container.Resolve<IPerformanceTracer>();
}
}
Relevant portion of config file:
<register type="IPerformanceTracer" mapTo="PerformanceTracer">
<lifetime type="PerWebRequest"/>
</register>
<register type="IPerformanceTracerFactory" mapTo="PerformanceTracerFactory"/>
I have another question. In case if the above way of configuring and injecting the dependency using code is correct, then I think I do not need the config entries. I can always use the suitable overload to push the custom lifetime manager. In case, I would want to achieve the same thing using only config file, then how do I code the solution?
If you use a container-based factory you don't have to register/resolve your IPerformanceTracer in each call.
Register the mapping IPerformanceTracer --> PerformanceTracer once in your config file and use a ParameterOverride when you resolve your interface.
public IPerformanceTracer CreateInstance(string operationTitle)
{
return _container.Resolve<IPerformanceTracer>(new ParameterOverride("nameOfTheParameterInTheConstructorOfPerformanceTracer", operationTitle);
}

Getting OSGi services from a bundle in Sling/CQ

I am using Day CQ. I want to store some data in a SQL Server DB, using the connection pool available in the Felix console. I can do this from a JSP, by using the "sling" object of type SlingScriptHelper defined in the defineObjects tag
sling.getService(DataSourcePool.class).
However, I want to use a servlet created in an OSGi bundle to handle requests from the client. The servlet doesn't have a defineObjects tag, so the "sling" object is not defined. I don't see a way to create a valid SlingScriptHelper object in my servlet, but it seems like it has to be possible.
Is there a way?
To get a service from a java OSGi component you don't need the SlingScriptHelper, you can either use the BundleContext.getService(...) method, or use SCR annotations to let SCR inject the service in your component.
As an example, you can look at how some components in Sling's Slingbucks sample use SCR annotations, the ConfirmedOrdersObserver class for example gets the SlingRepository in this way:
#Reference
private SlingRepository repository;
See http://felix.apache.org/site/apache-felix-maven-scr-plugin.html for the Maven plugin that handles these annotations.
You can use the BundleContext to get to the Service, by using the #getServiceReference and #getService methods. For example, if you were interested in the ResourceResolverFactory, you could get it like so:
BundleContext bundleContext = FrameworkUtil.getBundle(MyClass.class).getBundleContext();
ServiceReference factoryRef =
bundleContext.getServiceReference(ResourceResolverFactory.class.getName());
ResourceResolverFactory resolverFactory =
(ResourceResolverFactory) bundleContext.getService(factoryRef);
YourClass obj = this.getSlingScriptHelper().getService(yourclass.class);
obj.whatever();

Resources