I have a question about testing.
there is a controller with handler methods :
#Controller
#RequestMapping("/something")
public class MyController{
#RequestMapping(value = "/getSomething" , method = POST, produces = {JSON}, consumes = {JSON})
#ResponseBody
public MyClass2 getSomething(#RequestBody MyClass myObj) {
.........
}
}
Should I do any annotation's virification in my tests?
Like :
#Test
public void verityMethodGetSomethihg(){
//check that there is the POST method
//check that the method produces a JSON
//check that the method consumes a JSON
}
PS
Also , should do I check anywhere that there is method-handler a mapping for /getSomething?
Thanks
What you should do is up to you. If you consider it's a useful test to have, then do it. If you consider it's useless because, for example, you have an extensive functional test suite that tests your application, then don't.
Now how to do it? Spring MVC comes with a testing framework allowing to start a fake web application context, send a request to your app and test the result. It's extensively described in the documentation.
Related
I am trying to make spring boot application & swagger. Application is for REST service provide. I have made application running each page.
I have made a simple controller that have RequestMapping("/group/user/contact").
Which is working fine.
I am trying to do something like RequestMapping("/group/{type}/contact") at class level.
So my question is that is it possible ?
If yes then just want some basic guidance. and if no then fine.
My all request working fine. All request came from CORS filter class.
You can do this, the handler method should look something like
#Controller
#RequestMapping("/group/{type}/contact")
public class ClassLevelPathVariableController {
#ResponseBody
#RequestMapping(method = RequestMethod.GET)
public String classLevelMapping(#PathVariable String type) {
return type;
}
}
In this setup a GET request like e.g. /group/test/contact would be handled by the classLevelMapping method and the type variable will be populated with the value "test"
Below is my controller. My program generates an output, based on a form input. Across the project, there are multiple input forms, that generate the output object. So, the essential flow is the same. So I want a single multi-action controller that does all of that.
Challenges:
1. The service classes change. Although all services implement the same interface, and controller calls the same interface method.
2. The input objects change. Although the input objects do not have any methods other than setters, and getters. So I let them all implement an empty interface.
Questions:
How do I change the qualifier, based on the path. Can I use path variables?
Suppose the path has this value -> singleton. Then my corresponding bean names would be singletonService and singletonInput. I want to make a constant class that has stores this mapping information. So, can I call that from inside the qualifier, using some Spring Expression Language? Example, instead of Qualifier(variablePathName) -> Qualifier(getQualifierName['variablePathName']) Something like that?
Please also clarify the theory behind this. From what I understand, beans are created, autowired before the Request are mapped... Does this mean that what I'm trying to achieve here is simply not possible. In that case, would you suggest making Controller-service pairs for handling each request, with basically the same code? But I feel there must be some way to achieve what I'm trying...
Code:
#Cotroller
#RequestMapping(value="/generate/{path}")
public class TestController {
#Autowired
#Qualifier(......)
private IService service;
#Autowired
#Qualifier(......)
IUserInput userInput;
#RequestMapping(method = RequestMethod.POST)
//Some handler method
}
You're right in that the autowiring is all done once up front (point 3). You wouldn't be able to achieve what you want using fields annotated #Autowired and #Qualifier - as these fields would always reference the same bean instance.
You may be better to ask Spring for the particular service bean by name - based on the path variable. You could do it within a single controller instance. For example:
#Cotroller
#RequestMapping(value="/generate/{path}")
public class TestController {
#Autowired
private ApplicationContext applicationContext;
#RequestMapping(method = RequestMethod.POST)
public String someHandlerMethod(#PathVariable String path) {
IService service = (IService) applicationContext.getBean(path + "Service");
IUserInput userInput = (IUserInput) applicationContext.getBean(path + "UserInput");
// Logic using path specific IService and IUserInput
}
}
I have the following method I need to test with Moq. The problem is that each method called in the switch statement is private, including the PublishMessage at the end. But this method (ProcessMessage) is public. How can I test this so that I can ensure the calls are made depending on the parameter? Note that I'm not testing the private methods, I just want to test the "calls". I'd like to mock these private methods and check if they are called using Setup, but Moq does not support mocking private methods.
public void ProcessMessage(DispenserMessageDataContract dispenserMessage)
{
var transOptions = new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted };
using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew, transOptions))
{
switch (dispenserMessage.Type)
{
case DispenserMessageType.AckNack:
UpdateAckNackMessageQueue(dispenserMessage);
break;
case DispenserMessageType.FillRequest:
CreateFillRequestMessageQueue(dispenserMessage);
break;
case DispenserMessageType.FillEvent:
UpdateFillEventMessageQueue(dispenserMessage);
break;
case DispenserMessageType.RequestInventory:
CreateRequestInventoryMessageQueue(dispenserMessage);
break;
case DispenserMessageType.ReceiveInventory:
CreateReceiveInventoryMessageQueue(dispenserMessage);
break;
}
scope.Complete();
}
PublishMessage(dispenserMessage);
}
You will have to change those private methods to atleast protected virtual to mock them and then use mock.Protected to mock them(http://blogs.clariusconsulting.net/kzu/mocking-protected-members-with-moq/). You can't mock private methods.
Moq (and few other frameworks) uses Castle Project's DynamicProxy to generate proxies on the fly at run-time so that members of an object can be intercepted without modifying the code of the class. That interception can only be done on public virtual and protected virtual methods.
See below URL for more information:
http://www.castleproject.org/projects/dynamicproxy/
You could extract the private method in another class and make them public, then mock those with Moq and verify that they have been called.
Moq is for mocking properties and methods declared in interfaces and or abstract properties and methods in classes.
The idea behind Moq-testing is that you test the interactions between your class-under-test and the rest of the world (its dependencies). Moq does this by creating a "mocked" implementation of the interface or a derivative of the abstract class with the abstract methods implemented.
Moq cannot override existing implementation like your private methods. This is not how Moq works.
Either you should test "ProcessMessage" with all possible input and expected output or you should refactor your class to delegate the calls to interface methods that you can mock with Moq. Testing private methods is a bad concept anyway. They are kept private for a reason, which is to hide the implementation such that it can change at will.
I prefer to add additional class (*Helper) and move on all my private methods to public. Then you can easily test your methods directly. I didn't find more elegant way to do that.
In some cases, you may need to alter the behavior of private method inside the class you are unit testing. You will need to mock this private method and make it return what needed for the particular case. Since this private method is inside your class under test then mocking it is little more specific. You have to use spy object.
Spy object
A spy is a real object which mocking framework has access to. Spied objects are partially mocked objects. Some their methods are real some mocked. I would say use spy object with great caution because you do not really know what is happening underneath and whether are you actually testing your class or mocked version of it.
public class PowerMockDemo
{
public Point callPrivateMethod() {
return privateMethod(new Point(1, 1));
}
private Point privateMethod(Point point) {
return new Point(point.getX() + 1, point.getY() + 1);
}
}
Then you will mock the Spy object
Hope that will help you,
Best wishes
I am new to Web Technology. I have a WebService called Sample. It references a dll with name Custom.dll. My WebMethod is returning a class from Custom.dll which is marked as Serialization.
// My custom class
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
[SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://somthing-something.mydomain.com/")]
public class CustomClass
{
public string id;
public string key;
}
// My Web Service method
[WebMethod]
public CustomClass MyWsMethod()
{
return new CustomClass{id="id", key="Key"};
}
Also to mention, my webservice is a WCF Service and has a asmx file in it.
I am consuming this webservice in my application and service referenced my webservice as localhostWS. My Application also references Custom.dll. When I am calling my webservice method then I am not able to get back the Custom.CustomClass object. I am returning localhostWS.CustomClass and also I am not able cast it to Custom.CustomClass.
CustomClass custom = localhostWS.MyWsMethod();
Here custom object is of type localhostWS.CustomClass but I was expecting Custom.CustomClass.
Can any body suggest me whats happening here. Please let know if I need to provide any further information. I have tried enough to be clear in my question.
Edit
I must also mention this, it will great to achieve this without changing any Client side code. Due to reasons it will not be possible to change that. However any suggestions are welcome.
I’m about to start work on an OpenRasta project (an xml over http web service). OpenRasta looks great but unfortunately worked examples seem few and far between on the internet. Looking at the test side of the project, if my handlers are returning strongly typed objects (not OperationResult), i.e.:
public class PersonHandler
...
public Person Get(int id)
{
...
How can I test for http status codes? (For example if the handler throws an uncaught exception). I’m not sure what level the tests pitch in at, and what needs mocking (using moq btw)
Any help appreciated, particularly coded examples!
I faced the same problem, and ended up writing my tests as integration tests at a much higher level, actually making real REST/HTTP calls through a simple HttpWebRequest client. This allowed me to check the HTTP response headers / status codes and double-check the JSON/XML serialization from the client's perspective, which was just as important as whether or not the operations succeeded.
I started by returning OperationResult from all my handlers, and used these to wrap the strongly-typed objects. My handlers all inherit from a base class with a few helper methods that make it easier to return a custom error with a user-friendly error message. The more I coded this up, the more my handlers resembled a ASP.NET MVC controller. e.g.:
public OperationResult GetById(int id)
{
try
{
// do stuff here
return OKResult( // some strongly-typed resource );
}
catch(SomeException ex)
{
return BadRequestResult(SomeErrorCode, ex.Message);
}
}
Then in the test client, it's pretty easy to just check the HTTP status code. Obviously this doesn't help much with mocking. I'm not sure what the best solution is, in fact I've favorited this question in the hope that someone answers it better than I can - but this has worked pretty well for me so far.
The handler is just a class--ideally with minimal dependencies--so your unit tests can just test the isolated logic in the class.
If you want to test for status codes, I recommend (based on very little experience!) using OpenRasta self-hosting.
Here's a test (somewhat changed) that I wrote recently:
[TestMethod]
public void POST_with_inaccurate_contentLength_returns_405()
{
var resource = GetResource();
IRequest request = new InMemoryRequest
{
HttpMethod = "POST",
Uri = new Uri("http://localhost/Resource"),
};
request.Headers.ContentLength = 16; //wrong!
request.Entity.Stream.Write(resource.Content, 0, resource.Content.Length);
var response = _host.ProcessRequest(request);
Assert.AreEqual(405, response.StatusCode);
}
I should add that the host is set up in the TestInitialize method as such:
_host = new InMemoryHost(new Configuration());
_host.Resolver.AddDependencyInstance(typeof(IFileResourceRepository), _repository, DependencyLifetime.Singleton);
...and is cleaned up in the TestCleanup method.