If I have a common static method in a class named Language.CheckLanguage(), and I want all action class execute() method will call CheckLanguage() like this
public String execute(){
Language.CheckLanguage();
// DO Business logic...
Return Action.SUCCESS;
}
Or any other convenient way?
Do it in a base Action, and extend it from any Action.
Then call super() as first row of every execute().
But, if you want it to be executed for every method, not only execute(), then you should write an Interceptor.
Related
I have a weird problem with integration testing restful controllers... In the following code snippet, when I make a post request from tests, the save method of the parent, RestfulController class is called instead of the save method of the child class, MyController and because they have different signatures, this ends up resulting in a UNPROCESSIBLE_ENTITY response.
class MyController extends RestfulController<MyDomain> {
static responseFormats = ['json', 'xml', 'hal']
MyController() {
super(MyDomain)
}
def save(MyCommand command) {
...
}
}
When I run the following test, the save() action of my controller's parent class, RestfulController gets executed, thus leading to UNPROCESSIBLE_ENTITY response, since I am using a Command object which is different from my domain class.
void "Test the save action correctly persists an instance"() {
when: "The save action is executed with valid data"
response = restBuilder.post(resourcePath) {
accept('application/json')
header('Authorization', "Bearer ${accessToken}")
json validJson
}
then: "The response is correct"
response.status == CREATED.value()
response.json.id
Vote.count() == 1
}
What can I do to fix this, please?
Overloading controller actions is not supported. You can override them, but you can't overload them.
What is happening is the framework is invoking the no-arg save() action in the parent class, which never invokes your method (nor should it).
You can rename your save(MyCommand command) so it doesn't have the same name as an action in your parent class and then provide a corresponding URL mapping and you will be on your way. Depending on what you want to do in the action, that may or may not be the best thing, but that is 1 path you can take.
I hope that makes sense.
I want to test methods in my controller, I know about this...
myController = new MyController();
A.CallTo(()=>myController.SomeMethodIWantToTest().Returns(someValueIAmTesting);
The problem is that inside that parameterless constructor, I call numerous methods in other assemblies that set values for private members,
public class MyController : Controller {
private ILoginBusiness loginBusiness;
private ISomethingElse somethingElse;
//... and so on...
public MyController(){
loginbusiness = ServiceFactory.GetLoginBusiness();
somethingElse = //some method in another assembly that initializes the value
//... and so on, calling methods in other assemblies that initialize the private members...
}
public ActionResult SomeMethodIWantToTest(){ }
}
So how do I isolate all those method calls in my constructor (so I'm not calling methods in those other assemblies?)
First,
myController = new MyController();
A.CallTo(()=>myController.SomeMethodIWantToTest().Returns(someValueIAmTesting);
Will result in an error, as A.CallTo only handles calls to fakes (and there should be an extra ) after …ToTest()).
Second, the general approach that is taken in this sort of situation is called Dependency Injection. Instead of having a class make all its dependencies (in your case, by calling methods from other assemblies), you have its dependencies provided to it.
Assuming you're able to start injecting dependencies, you're almost home. You're already relying on interfaces inside MyController, so then you can use FakeItEasy to supply fakes to MyController, avoiding calls to the out-of-assembly methods.
I was thinking about adding a new Interface (like validationAware, etc.) for sturts 2. The methods of the interface would be methods that sets specific parameters that has to be present inside the request.
For example, consider this Interface :
public interface MyCustomInterfaceForActions {
/**
* Set a specific parameter into the request
*/
public void setMyParameter1InRequest(HttpServletRequest request, String myParameter);
/**
* Sets another specific parameter into the request
*/
public void setSecondParamInRequest(HttpServletRequest request, String myParameter);
}
The thing is that I don't want to have to "call" the method "setParameterInRequest" in "execute" methods of each actions that implements that interface.
Also, I want to "force" the actions to set specific parameters into the request.
Is there a way to do that without having to call the "set" methods inside all "executes" methods of my actions? For example, can I extend a struts' "actionExecutor" (I made that name up) and change it's behavior to check if the class implements "MyCustomInterfaceForActions" and call the "set" methods if it's the case?
Or better yet, just check to see if the interface is implemented and just add those parameters to the request anyway, without having to implement methods?
Why not simply use the Preparable, interface. This way you can do your initialization in the prepare() method?
In a Service of a Grails project, I like to find, at run time, the arguments of Dynamic Methods in order to inform callers.
Also, I like to call the method and if doesn't exist to return an error,
I will appeciate any help.
You can configure URLMappings in grails to get the value of the dynamic method and call it against your object for example you can do the following
In your urlMappings.groovy define a mapping with two embedded variables object and method
"/$object/$method" (controller:"api",action:"invoke")
Define a 'api' controller with an invoke action. See code below with the logic on how to invoke the method on the object
import org.codehaus.groovy.grails.commons.ApplicationHolder as AH
class ApiController {
def invoke = {
def object = params.object
def method = params.method
def args
if(object) {
def domainClass = AH.application.domainClasses.find{it.name == method}?.clazz
if(domainClass.metaClass.getStaticMetaMethod(method,args)) {
domainClass.metaClass.invokeStaticMethod(target,input.method,args)
}
}
}
}
In my example, I assumed that you're calling a static dynamic finder on the domain class. You can generalize this to handle instance methods as well. You need however to provide more information such as the object id, in your request to load the object and call the method against it.
"/$object/$id/$method" (controller:"api",action:"invoke")
-Ken
Not sure I understand your question, but the last part about checking if you can call a method on an object, this can be done by checking the meta class of the object you are dealing with like this.
obj.metaClass.respondsTo(obj, 'theMethodYouWantToCall')
obj is the object you want to call the method on, and theMethodYouWantToCall is the name of the method you want to call.
respondsTo will return an empty list [] if the method you are trying to call is not found
I'm writing some unit tests to assert that all our controller action methods are marked with proper custom attributes, but I don't really know what the criteria is for determining whether a public method can act as MVC action or not.
I would assume that a criteria could be the return value type (it has to be ActionResult or a derivative). Is this true? What about static methods?
For a method to be considered an action, it has to meet the following criteria:
It must be public and not static
It must not have a "special" name in order to exclude constructors, events etc.
It must not be defined on System.Web.Mvc.Controller or any other base class in order to exclude .ToString() and family.
Generic methods will throw an exception, yet for some reason they are considered actions. As for the return type, it does not necessarily have to be an ActionResult, since you can return e.g. a string for text data.
I beleive all public methods in a controller are treated as actions - even one returning a string.
Determining the true list of actions on a controller is a tricky problem. The only correct answer is that it "depends"! The list that Saulius gave is pretty much correct - if you're using the default ControllerActionInvoker - which of course, most people use.
If you want to avoid duplicating the logic I would recommend using the ControllerActionInvoker itself to get the list of actions and then verify the contents of the list that it returns.
You'll have to write a class that derives from ControllerActionInvoker so that you can call the GetControllerDescriptor() method. The return value of that method is a ControllerDescriptor, which is an abstract descriptor of what the controller has. You can then call GetCanonicalActions(), which returns a list of ActionDescriptors. Each of those items represents what is typically and action method.
To hook it all up you'll need to:
Instantiate your controller
Set its ActionInvoker property to be an instance of your custom invoker
Create a ControllerContext instance that has its Controller instance set to your controller
Call a new public method on your invoker that in turn calls GetControllerDescriptor()
Then verify the results and you're done!
Of course, I haven't tried any of this but in theory it all works :)