Using Spring to inject EasyMock mocks causes ClassCastException - unit-testing

I am trying to get Spring to inject EasyMock mocks in my unit tests.
In my applicationContext.xml, I have this:
<bean id="mockService" class="org.easymock.EasyMock" factory-method="createMock" name="MockService">
<constructor-arg index="0" value="my.project.Service"/>
</bean>
In my unit test I have this:
#Autowired
#Qualifier("mockService")
private Service service;
public void testGetFoo() {
Foo foo = new Foo();
expect(service.findFoo()).andReturn(foo);
replay(service); // <-- This is line 45, which causes the exception
// Assertions go here...
}
When I try to run my test, I get this stack trace:
java.lang.ClassCastException: org.springframework.aop.framework.JdkDynamicAopProxy
at org.easymock.EasyMock.getControl(EasyMock.java:1330)
at org.easymock.EasyMock.replay(EasyMock.java:1279)
at TestFooBar.testGetFoo(TestVodServiceLocator.java:45)
I am quite new to both Spring and EasyMock, but it seems to me that the error is caused by EasyMock trying to call a method on what it assumes to be an instance of EasyMock, but is in reality a dynamic proxy created by Spring. As I understand it, dynamic proxies only implement the methods defined in the interface, in this case the interface for Service.
What I don't understand is that from what I read (also here), what I'm trying to achieve at least seems to be possible.
So my question is: What I'm I not doing or what am I doing wrong?

You can also create a helper method to unwrap the EasyMock proxy from the Spring proxy to define expected behaviour then:
public static <T> T unwrap(T proxiedInstance) {
if (proxiedInstance instanceof Advised) {
return unwrap((T) ((Advised) proxiedInstance).getTargetSource().getTarget());
}
return proxiedInstance;
}
Note the recusive call as in worst case you have multiple proxies wrapped around the actual target.

Solved!
I had overlooked this in my applicationContext.xml:
<bean id="txProxyAutoCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Service</value>
<!-- ^^^^^^^^
This is the problem!
-->
</list>
</property>
<property name="interceptorNames">
<list>
<value>txAdvisor</value>
</list>
</property>
</bean>
... which causes Spring to automatically create proxy objects for all beans with names that end in "Service".
My solution was to explicitly list the beans instead of using a wild card. This seems a little brittle to me, however, so if anyone knows how to specify all *Service beans except FooService, I would be grateful.

Something's odd here. You're clearly quickly mastering both Spring and EasyMock. The autoproxies, the factory methods, all good signs that you're diving deep into Spring's capabilities.
Still, it's kind of odd that you're injecting a mock bean into a class at all. You may have a great reason, but to me it's a code smell. I'd advise you to consider only wiring in real services into your test classes and then initializing the mock objects as needed. Why spend 3 lines in java and another 3 lines in XML (plus 1 line to reset them) to create a mock object with no dependencies? Just say Service service = (Service)createMock(Service.class). I would advise creating them in the methods that you need them for, set expectations, inject, use them, and then discard them. In your model, you'll have to remember to reset the mock object every time you use it, which is less clear than just creating a new one.
Of course, this is a style issue and not a correctness issue, so ignore as desired.

I know this question is old, but I just stumbled upon it searching for a similar problem.
The problem is that Spring doesn't know the type of the mock object. The method you use looks like this:
public static <T> T createMock(final Class<T> toMock) {
return createControl().createMock(toMock);
}
Spring isn't smart enough to derive T from the constructor argument (at least the last time I've checked), so it thinks the returned object is of type java.lang.Object. As a consequence, the created proxy doesn't implement my.project.Service and therefore can't be injected.
The answer therefore is to tell Spring the required type.

Related

Service #Transactional exception translation

I have a web service with an operation that looks like
public Result checkout(String id) throws LockException;
implemented as:
#Transactional
public Result checkout(String id) throws LockException {
someDao.acquireLock(id); // ConstraintViolationException might be thrown on commit
Data data = otherDao.find(id);
return convert(data);
}
My problem is that locking can only fail on transaction commit which occurs outside of my service method so I have no opportunity to translate the ConstraintViolationException to my custom LockException.
Option 1
One option that's been suggested is to make the service delegate to another method that's #Transactional. E.g.
public Result checkout(String id) throws LockException {
try {
return someInternalService.checkout(id);
}
catch (ConstraintViolationException ex) {
throw new LockException();
}
}
...
public class SomeInternalService {
#Transactional
public Result checkout(String id) {
someDao.acquireLock(id);
Data data = otherDao.find(id);
return convert(data);
}
}
My issues with this are:
There is no reasonable name for the internal service that isn't already in use by the external service since they are essentially doing the same thing. This seems like an indicator of bad design.
If I want to reuse someInternalService.checkout in another place, the contract for that is wrong because whatever uses it can get a ConstraintViolationException.
Option 2
I thought of maybe using AOP to put advice around the service that translates the exception. This seems wrong to me though because checkout needs to declare that it throws LockException for clients to use it, but the actual service will never throw this and it will instead be thrown by the advice. There's nothing to prevent someone in the future from removing throws LockException from the interface because it appear to be incorrect.
Also, this way is harder to test. I can't write a JUnit test that verifies an exception is thrown without creating a spring context and using AOP during the tests.
Option 3
Use manual transaction management in checkout? I don't really like this because everything else in the application is using the declarative style.
Does anyone know the correct way to handle this situation?
There's no one correct way.
A couple more options for you:
Make the DAO transactional - that's not great, but can work
Create a wrapping service - called Facade - whose job it is to do exception handling/wrapping around the transactional services you've mentioned - this is a clear separation of concerns and can share method names with the real lower-level service

MVC 3: How to learn how to test with NUnit, Ninject, and Moq?

Short version of my questions:
Can anyone point me toward some good, detailed sources from which I
can learn how to implement testing in my MVC 3 application, using
NUnit, Ninject 2, and Moq?
Can anyone here help clarify for me how Controller-Repository
decoupling, mocking, and dependency injection work together?
Longer version of my questions:
What I'm trying to do ...
I am currently beginning to create an MVC 3 application, which will use Entity Framework 4, with a database first approach. I want to do this right, so I am trying to design the classes, layers, etc., to be highly testable. But, I have little to no experience with unit testing or integration testing, other than an academic understanding of them.
After lots of research, I've settle on using
NUnit as my testing framework
Ninject 2 as my dependency injection framework
Moq as my mocking framework.
I know the topic of which framework is best, etc., could enter into this, but at this point I really don't know enough about any of it to form a solid opinion. So, I just decided to go with these free solutions which seem to be well liked and well maintained.
What I've learned so far ...
I've spent some time working through some of this stuff, reading resources such as:
Implementing the Repository and Unit of Work Patterns in an
ASP.NET MVC Application
Building Testable ASP.NET MVC Applications
NerdDinner Step 12: Unit Testing
Using Repository and Unit of Work patterns with Entity Framework
4.0
From these resources, I've managed to workout the need for a Repository pattern, complete with repository interfaces, in order to decouple my controllers and my data access logic. I have written some of that into my application already, but I admit I am not clear as to the mechanics of the whole thing, and whether I am doing this decoupling in support of mocking, or dependency injection, or both. As such, I certainly wouldn't mind hearing from you guys about this too. Any clarity I can gain on this stuff will help me at this point.
Where things got muddy for me ...
I thought I was grasping this stuff pretty well until I started trying to wrap my head around Ninject, as described in Building Testable ASP.NET MVC Applications, cited above. Specifically, I got completely lost around the point in which the author begins describing the implementation of a Service layer, about half way into the document.
Anyway, I am now looking for more resources to study, in order to try to get various perspectives around this stuff until it begins to make sense to me.
Summarizing all of this, boiling it down to specific questions, I am wondering the following:
Can anyone point me toward some good, detailed sources from which I
can learn how to implement testing in my MVC 3 application, using
NUnit, Ninject 2, and Moq?
Can anyone here help clarify for me how Controller-Repository
decoupling, mocking, and dependency injection work together?
EDIT:
I just discovered the Ninject official wiki on Github, so I'm going to start working through that to see if it starts clarifying things for me. But, I'm still very interested in the SO community thoughts on all of this :)
If you are using the Ninject.MVC3 nuget package, then some of the article you linked that was causing confusion will not be required. That package has everything you need to start injecting your controllers which is probably the biggest pain point.
Upon installing that package, it will create a NinjectMVC3.cs file in the App_Start folder, inside that class is a RegisterServices method. This is where you should create the bindings between your interfaces and your implementations
private static void RegisterServices(IKernel kernel)
{
kernel.Bind<IRepository>().To<MyRepositoryImpl>();
kernel.Bind<IWebData>().To<MyWebDAtaImpl>();
}
Now in your controller you can use constructor injection.
public class HomeController : Controller {
private readonly IRepository _Repo;
private readonly IWebData _WebData;
public HomeController(IRepository repo, IWebData webData) {
_Repo = repo;
_WebData = webData;
}
}
If you are after very high test coverage, then basically anytime one logical piece of code (say controller) needs to talk to another (say database) you should create an interface and implementation, add the definition binding to RegisterService and add a new constructor argument.
This applies not only to Controller, but any class, so in the example above if your repository implementation needed an instance of WebData for something, you would add the readonly field and the constructor to your repository implementation.
Then when it comes to testing, what you want to do is provide mocked version of all required interfaces, so that the only thing you are testing is the code in the method you are writing the test for. So in my example, say that IRepository has a
bool TryCreateUser(string username);
Which is called by a controller method
public ActionResult CreateUser(string username) {
if (_Repo.TryCreateUser(username))
return RedirectToAction("CreatedUser");
else
return RedirectToAction("Error");
}
What you are really trying to test here is that if statement and the return types, you do not want to have to create a real repository that will return true or false based on special values you give it. This is where you want to mock.
public void TestCreateUserSucceeds() {
var repo = new Mock<IRepository>();
repo.Setup(d=> d.TryCreateUser(It.IsAny<string>())).Returns(true);
var controller = new HomeController(repo);
var result = controller.CreateUser("test");
Assert.IsNotNull(result);
Assert.IsOfType<RedirectToActionResult>(result)
Assert.AreEqual("CreatedUser", ((RedirectToActionResult)result).RouteData["Action"]);
}
^ That won't compile for you as I know xUnit better, and do not remember the property names on RedirectToActionResult from the top of my head.
So to sum up, if you want one piece of code to talk to another, whack an interface in between. This then allows you to mock the second piece of code so that when you test the first you can control the output and be sure you are testing only the code in question.
I think it was this point that really made the penny drop for me with all this, you do this not necessarily becase the code demands it, but because the testing demands it.
One last piece of advice specific to MVC, any time you need to access the basic web objects, HttpContext, HttpRequest etc, wrap all these behind an interface as well (like the IWebData in my example) because while you can mock these using the *Base classes, it becomes painful very quickly as they have a lot of internal dependencies you also need to mock.
Also with Moq, set the MockBehaviour to Strict when creating mocks and it will tell you if anything is being called that you have not provided a mock for.
Here is the application that I'm creating. It is open source and available on github, and utilizes all of the required stuff - MVC3, NUnit, Moq, Ninject - https://github.com/alexanderbeletsky/trackyt.net/tree/master/src
Contoller-Repository decoupling is simple. All data operations are moved toward the Repository. Repository is an implementation of some IRepository type. The controller never creates repositories inside itself (with the new operator) but rather receives them either by constructor argument or property.
.
public class HomeController {
public HomeController (IUserRepository users) {
}
}
This technique is called "Inversion of Control." To support inversion of control you have to provide some "Dependency Injection" framework. Ninject is a good one. Inside Ninject you associate some particular interface with an implementation class:
Bind<IUserRepository>().To<UserRepository>();
You also substitute the default controller factory with your custom one. Inside the custom one you delegate the call to the Ninject kernel:
public class TrackyControllerFactory : DefaultControllerFactory
{
private IKernel _kernel = new StandardKernel(new TrackyServices());
protected override IController GetControllerInstance(
System.Web.Routing.RequestContext requestContext,
Type controllerType)
{
if (controllerType == null)
{
return null;
}
return _kernel.Get(controllerType) as IController;
}
}
When the MVC infrastructure is about to create a new controller, the call is delegated to the custom controller factory GetControllerInstance method, which delegates it to Ninject. Ninject sees that to create that controller the constructor has one argument of type IUserRepository. By using the declared binding, it sees that "I need to create a UserRepository to satisfy the IUserRepository need." It creates the instance and passes it to the constructor.
The constructor is never aware of what exact instance would be passed inside. It all depends on the binding you provide for that.
Code examples:
https://github.com/alexanderbeletsky/trackyt.net/blob/master/src/Web/Infrastructure/TrackyServices.cs https://github.com/alexanderbeletsky/trackyt.net/blob/master/src/Web/Infrastructure/TrackyControllerFactory.cs https://github.com/alexanderbeletsky/trackyt.net/blob/master/src/Web/Controllers/LoginController.cs
Check it out : DDD Melbourne video - New development workflow
The whole ASP.NET MVC 3 development process was very well presented.
The third party tools I like most are:
Using NuGet to install Ninject to enable DI throughout the MVC3
framework
Using NuGet to install nSubstite to create mocks to enable unit
testing

Optional dependency injection for unit testing

I'm considering my options for setting up a class for unit testing. This particular class should ALWAYS use the same soap client configuration under normal circumstances. I feel like users of the class shouldn't need to be concerned with setting up a soap client when they use it. Or, even be aware that it uses soap at all.
Really the only exception is in unit testing. I'll need to be able to mock the Soap_Client. I've come up with the following approach where i create the soap client in the constructor and can optionally set it with setSoapClient().
class WebServiceLayer
{
const WSDL_URL = 'https://www.example.com/?WSDL';
private $soapClient;
public function __construct()
{
$this->soapClient = new Soap_Client(self::WSDL_URL);
}
public function setSoapClient(Soap_Client $soapClient)
{
$this->soapClient = $soapClient;
}
public function fetchSomeResponse()
{
$soapClient = $this->soapClient;
return $soapClient->someRequest();
}
}
Is this a valid way to handle this? The only problem i see with it, is that im instantiating the client in the constructor which "i've heard" is something to avoid.
I've run into this dilemma before on other classes, so it would be really nice to get peoples opinions on this.
Looks fine to me... you're using standard Setter injection. The only strange thing is returning a new client in the Getter. Why not return null if it hasn't been injected?

Unit tests for Liferay portlets

Does anyone know how to run unit tests for Liferay portlets? I have found a lot of posts about it (e.g. http://agile-reflections.opnworks.com/2010/06/portlet-unit-testing-with-liferay-6.html) but none works nonetheless.
This may be overkill, but if you're looking for an Enterprise approach with continuous integration testing, this blog gives a very good example: Continuous integration on Liferay: running your Selenium 2 tests on the Tomcat 6 bundle
Unit testing Liferay portlets is quite complicated when ServiceBuilder is utilized.
The reason is that it generates quite heavy services that contain references not only to beans within Portlet, but even to the Portal beans generated by ServiceBuilder.
There are tools like InitUtil.init(); that lets you at least instantiate and use ServiceBuilder entities... not EntityServices though. For that you'd have to use SpringUtil.loadContext(); that requires
System.setProperty("external-properties", "testing.properties");
where testing.properties contains :
spring.configs=META-INF/ext-spring.xml,\
META-INF/base-spring.xml,\
META-INF/dynamic-data-source-spring.xml,\
META-INF/infrastructure-spring.xml,\
META-INF/shard-data-source-spring.xml,\
META-INF/hibernate-spring.xml,\
META-INF/portlet-spring.xml
These are spring definitions to be loaded for testing application context. It all would be OK, but beans from portlet-spring.xml are those heavy services containing references to Portal bean definitions like ResourceService, UserLocalService, CounterLocalService and you would have to load even META-INF/portal-spring.xml and trust me, it's not that easy cause then you'd have to load quite a lot of other stuff.
THE ANSWER:
The truth is, that you most likely won't have to unit test portlet SB services, never. They represent entities with persistence and service layer around. Something that is not to be tested. You just have to mock them and stub their methods, right ?
And the best way for junit and integration testing as to mocking is not using *LocalServiceUtil static classes in your application, because it is almost unmockable.
You just need to create a Spring FactoryBean :
public class PortalFactoryBean implements FactoryBean {
private Class type;
public void setType(final Class type) {
this.type = type;
}
#Override
public Object getObject() throws Exception {
return PortalBeanLocatorUtil.locate(type.getName());
}
#Override
public Class getObjectType() {
return type;
}
}
public class PortletFactoryBean implements FactoryBean {
private Class type;
public void setType(final Class type) {
this.type = type;
}
#Override
public Object getObject() throws Exception {
return PortletBeanLocatorUtil.locate(type.getName());
}
#Override
public Class getObjectType() {
return type;
}
}
<bean id="somePortalBean" class="example.spring.PortalFactoryBean" lazy-init="true">
<property name="type" value="com.liferay.some.util.SomeService"/>
</bean>
<bean id="somePortletBean" class="example.spring.PortletFactoryBean" lazy-init="true">
<property name="type" value="com.example.SomeService"/>
</bean>
#Autowired
private SomeService somePortalBean;
Writing unit/integration tests for this portlet would be quite easy, right ? You just create a spring context for testing and you mock these services :
Using Service Builder is worth it, but you must have some Spring knowledge and play with it for some time. Then it spares a lot of time because it is easy to maintain.
You need to have some third party libraries on classpath.
THe key point is having even portal-impl.jar and other portal dependencies on classpath and having InitUtil.initWithSpring(boolean); load up core spring xml configs that you specify in spring-ext.properties in spring.congigs property, only those services you need. You may need no portal services and only the portlet ones, but this is a problem because your portlet services generated by service builder use the portal services.
Using service builder just needs good knowledge of spring and classloading.
But you need to understand the infrastructure before doing that. There are quite a lot of hacks needed... Like
BeanLocator beanLocator = new BeanLocatorImpl(PortalClassLoaderUtil.getClassLoader(), ac);
PortletBeanLocatorUtil.setBeanLocator("portlet", beanLocator);

Strategies to mock a webservice

I'm implementing a client consuming a webservice. I want to reduce dependencies and decided to mock the webservice.
I use mockito, it has the advantage vs. EasyMock to be able to mock classes, not just interfaces. But that's not the point.
In my test, I've got this code:
// Mock the required objects
Document mDocument = mock(Document.class);
Element mRootElement = mock(Element.class);
Element mGeonameElement = mock(Element.class);
Element mLatElement = mock(Element.class);
Element mLonElement = mock(Element.class);
// record their behavior
when(mDocument.getRootElement()).thenReturn(mRootElement);
when(mRootElement.getChild("geoname")).thenReturn(mGeonameElement);
when(mGeonameElement.getChild("lat")).thenReturn(mLatElement);
when(mGeonameElement.getChild("lon")).thenReturn(mLonElement);
// A_LOCATION_BEAN is a simple pojo for lat & lon, don't care about it!
when(mLatElement.getText()).thenReturn(
Float.toString(A_LOCATION_BEAN.getLat()));
when(mLonElement.getText()).thenReturn(
Float.toString(A_LOCATION_BEAN.getLon()));
// let it work!
GeoLocationFetcher geoLocationFetcher = GeoLocationFetcher
.getInstance();
LocationBean locationBean = geoLocationFetcher
.extractGeoLocationFromXml(mDocument);
// verify their behavior
verify(mDocument).getRootElement();
verify(mRootElement).getChild("geoname");
verify(mGeonameElement).getChild("lat");
verify(mGeonameElement).getChild("lon");
verify(mLatElement).getText();
verify(mLonElement).getText();
assertEquals(A_LOCATION_BEAN, locationBean);
What my code shows is that I "micro-test" the consuming object. It's like I would implement my productive code in my test. An example for the result xml is London on GeoNames.
In my opinion, it's far too granular.
But how can I mock a webservice without giving everystep? Should I let the mock object just return a XML file?
It's not about the code, but the approach.
I'm using JUnit 4.x and Mockito 1.7
I think the real problem here is that you have a singleton that calls and creates the web service so it is difficult to insert a mock one.
You may have to add (possibly package level) access to the singleton class. For example if the constructor looks something like
private GeoLocationFactory(WebService service) {
...
}
you can make the constructor package level and just create one with a mocked web service.
Alternatively you can set the webservice by adding a setter method, although I don't like mutable Singletons. Also in that case you have to remember to unset the webservice afterwards.
If the webservice is created in a method you might have to make the GeoLocationFactory extensible to substitute the mock service.
You may also look into remove the singleton itself. There are articles online and probably here on how to do that.
you really want to be mocking the results returned from the webservice to the code that will be using the result. In your example code above you seem to be mocking mDocument but you really want to pass in an instance of mDocument that has been returned from a mocked instance of your webservice and assert that the locationBean returned from the geoLocationFetcher matches the value of A_LOCATION_BEAN.
The easiest option would be to mock the WebService client,
when(geoLocationFetcher.extractGeoLocationFromXml(anyString()))
.thenReturn("<location/>");
You can modify the code to read the response xml from the file system.
Sample code can be found here: Mocking .NET WebServices with Mockito