Tag Archives: spring-mvc

Unit test – call the agel out of the stone

Angel

Angel, please come out of the stone

“I saw the angel in the marble and carved until I set him free” – Michelangelo

After the previous post when I managed to make Spring context wired for Unit test to run, now there’s more thing into it. Well, I gave my Test class the ability to do IOC (Inversion of Control), and from now they can call service beans, access databases, and so on… It seems the remaining should be easy, since the hardest part has been completed.

Well, things don’t easily go as we expect, in lots of occasions.

I actually made a running code, but when I try writing my first unit tests for my current working web-application, things turn bad. It turns out that I can’t write much meaningful non-trivial test, without making test-running-time tremendous slow. Why? It’s because:

1. Most of my code logic lies in the service. AND the service (in this project) OFTEN (if not always) works with Database. And when I says Database, it means the test is not the unit test anymore. It’s an Integration Test.

2. There’s some logic in my project which doesn’t relate to database. But I feels pretty confident about them – they are mostly simple. According to Pareto’s 80/20 rule, I don’t want to write tests that doesn’t enhance maintenance ability.

Those may be (some of) the reasons that my seniors don’t encourage me to write unit test. Unit tests are meant to be fast. If it’s not fast, there’s no reason to run it frequently, to help refactoring or development.

Another problem I meet is to set up the Database to a known state before running the test. Only then the test results will have some meanings.

So… are the efforts all useless. Absolutely no. The main problem here is that I need to stop regression bugs, by regularly running some kind of test. Whatever it is, but let me find bugs soon, and stop the system broken by ill-refactoring.

“And I have found the solution. The way to call the angel out of the stone”. If I can put up an in-memory database instead of Postgres, the running-time will be fast. I can also prepare the environment by database script or bootstrap code.

DBUnit seems to be a fair choice for a solution.

Configure UnitTesting with Autowired in Spring context

/* Vietnamese:  Một bài viết trình bày cách viết Unit Test sử dụng Dependency-Injection(Autowiring) trong Spring Framework. */

Unit-testing is surely not a new idea, since it was proposed around the 1980s. But it’s still one of the core concepts of Test Driven Development, Agile programing, Scrum,… & some other “hot” programming methodology that arise recently. In “Clean code”, Robert C. Martin writes: “If you want to write a line of debug/log message, consider writing a test instead”.

Those ideas are really cool – if you want to know more about how writing tests stop regression bugs, improve productivity & help the designs overall, go on & read “Clean code”. I will return to the topic here: How to write Unit test in Spring context.

The second I read those above lines of Martin, I decided to try it right away. But to do Unit test in a Spring web project, I need a way to inject my services into the test case (well, there’s a HUGE pile of services). The way is easy, but only if you know what to do.

It took me quite a time to make a running system.

Here’s how I did it:

package longle.action.services;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/main/webapp/WEB-INF/applicationContext.xml",
"file:src/main/webapp/WEB-INF/actions-servlet.xml"})
public class ActionServiceImplTest {
	@Autowired
	private ActionService actionService;

	@Test
	public void testHelloAction() {
		assert actionService.helloUnitTest().equals("Hello Unit Test, hope we have a good time together!");
	}
}

Hope that should cover the topic

Source code can be found here: http://www.mediafire.com/file/ww79etrez40j4gl/action.zip

Reference: (not all of these links are referred in this article. But every of them help me “go near the truth”, so I put them all here.)

  1. http://stackoverflow.com/questions/7313983/test-case-by-junit-how-to-read-web-xml
  2. http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/testing.html
  3. http://stackoverflow.com/questions/6546871/spring-junit-testing
  4. http://stackoverflow.com/questions/5733959/junit-custom-runner-with-spring-application-context
  5. http://stackoverflow.com/questions/8502327/application-context-and-spring-context-is-same
  6. http://stackoverflow.com/questions/8666720/configuration-problems-unable-to-locate-spring-namespacehandler-for-xml-schema
  7. http://stackoverflow.com/questions/412717/how-to-use-maven-surefire-plug-in-with-different-groups-for-test-and-integration
  8. http://maven.apache.org/plugins/maven-surefire-plugin/
  9. http://mekongnet.ru/index.php?mod=News&sid=37510&stprint=1

Warning about primitive ModelAttribute

Recently while working with Spring Framework 3.0, I stumbled upon a trap that might be a bug of Spring Framework. It costs our team lots of time & efforts, since the bug is like a mystery that happens randomly. Eventually we decide to take a work around, but it’s still take lots of time to change the way the system was working.

The mystery is called Model Attribute, a handy utility supported by Spring 3.x.

Personally, I like this feature a lot. The ModelAttribute Annotation way gives me the ability to declare and init a variable just once, then it will be automatically added into model of any action. For example:

@ModelAttribute("user")
public User getCurrentUser() {
return userService.getCurrentUser();
}

But a problem happen here & there when I use primitive type (long, int, …) or even their wrapper type (Long, Integer,…) for the ModelAttribute. An error just pop out of nowhere:

java.lang.NoSuchMethodException: long.()<init>

Following my senior hint, I even comes to the code of Spring Framework, and actually see that it try to call the default constructer of Long type. Since that constructer does not exist (certainly), it fails and brings up the error. The headache is that this thing does not always happen: I still can not figure what trigger it up. But the fact that it’s out there make me & our team change the course of the program: instead of an tidy assignment, now we need to call the same function again & again whenever we need that modelAttribute (almost always in my case).

I have put a question out there in StackOverflow, but it still get no-good answer. I wonder if I should raise a bug for Spring… but until then I think that this “brilliant” way shouldn’t be used.

Hope this post is useful for anyone come across the same problem.

Finding key issues of the framework

Website System

1. How to learn a framework fast?

2. To learn a framework, you should grasp the “key” issues. But how to know what is a key issue?

Those two questions are pinned in my head somehow.

Not long ago, I’m investigating MVC model in Spring Framework 3.0. Most of the concept is fine, but I have problems doing the work with Spring 3 annotation config. It just seems all the book out there mention about Spring 2.x syntax, which is “xml configuration”. It’s easy to understand because that Spring 3 just appear and it will take a relative time to make a book available. So my habit about following book guides was discarded aside. I must try to find another source.

According the advice of my seniors, I go to the Spring document & find most of the thing is already here. Enough details, though a bit complex to a not-quite-familiar-with-java coder. I struggle with those concept a bit. But by comparing the document to several examples, finally I got some “working things”, which is great.

But here comes the most complicated part: integrating between frameworks. In one of my projects, I should use Spring combined with Freemarker. I investigate, and luckily enough, find this page which tell me how to use Freemarker macro to perform bindings (it’s not an easy luck).

But WTH, I can’t find a way to use the formCheckboxes! I found no working sample, and I’m not alone.

Dozens people out there can’t find a way to use that macro.

And the solution?

Well, I write my own macros.

It took me quite a time before I relize that simple solution, and curse how stupid I am. Since the end results of freemarker is HTML, who cares if it was rendered by supported macro or customed macro?

When you know what actually happens inside that big system, the answer seems to be natural.


Still remember 2 questions at the beginning of this post?

I must says the truth, that I don’t know the best answer. But I have something that seems to work:

The solution depends on the needs. If you just use the surface of the libraries API as the common “players”, some popular tutorials might be enough. Parsing XML maybe a good example for this issue. With the same reason, I think with beginner, Grails (instead of Spring) is a good start, cause it requires little work to make a full-fledge simple application.

If you want to create a customized & not-so-popular web application, it requires more tons of work. And a solid background is preferable.

Annotation Validation in Spring Framework 3

/* Vietnamese: bài viết hướng dẫn một cách ngắn gọn cách thực hiện kiểm tra điều kiện của đối tượng (validation) bằng cách dùng ký hiệu (annotation) với Spring Framework */

Validation is not a problem in Spring Framework, at least, by the normal way.

But the “Validation by Annotation” is not that popular, since this utility was only available from Spring 3. Up to now I found no resource which give a short & comprehensive tutorial yet (at least to this time – 05/2011)

How to make annotation validation works in Spring Framework 3

1. Configure Maven to include Hibernate Validator

2. Setup default validator bean in config file:
[sourcecoce language="xml"]
<bean id=”validator” class=”org.springframework.validation.beanvalidation.LocalValidatorFactoryBean” />
[/sourcecode]

3. Add @annotation

Let’s see what is annotation validation in its action:

public class User implements Serializable {
        private long id;
        @NotNull(message=&quot;{user.name.notnull}
        @Length(max = 255, message=&quot;{user.name.length}&quot;)
	private String username;
	public void setUsername(String name) {
		this.username = name;
	}
	public int getUsername() {
		return username;
	}
}

Code for the controller:

@Controller
@RequestMapping(&quot;/administration/*&quot;)
public class AdministrationController {
    /**
     * For every request for this controller, this will
     * create a user instance for the form.
     */
    @ModelAttribute
    public User newRequest(@RequestParam(required=false) String id) {
        return (id != null ? userService.getUserById(id) : new User());
    }

    @RequestMapping(value=&quot;/editUser&quot;, method=RequestMethod.GET)
	public final String edit(@Valid User user, BindingResult result) throws Exception {

		if (user == null) {
			return &quot;redirect:/administration/manageUser&quot;;
		}

		return null;
	}

	@RequestMapping(value=&quot;/editUser&quot;, method=RequestMethod.POST)
	public final String updateUser(@Valid User user, BindingResult result) throws Exception {

		if (result.hasErrors()) {
			return null;
		}

		userService.updateUser(user);

		return &quot;redirect:/administration/manageUser&quot;;
	}
}

And in the end, for the jsp:

&lt;/pre&gt;
&lt;h1&gt;Edit Site User&lt;/h1&gt;
&lt;div&gt;
&lt;fieldset&gt;&lt;legend&gt;Edit Site User&lt;/legend&gt;
 &lt;input type=&quot;hidden&quot; name=&quot;userId&quot; value=&quot;${user.id}&quot; /&gt;
				&lt;p&gt;
					&lt;form:label for=&quot;id&quot; path=&quot;id&quot;&gt;Id&lt;/form:label&gt;
					&lt;br /&gt;
					&lt;form:input path=&quot;id&quot; readonly=&quot;true&quot; /&gt;
					&lt;font color=&quot;red&quot;&gt;&lt;form:errors path=&quot;id&quot; /&gt;
					&lt;/font&gt;
				&lt;/p&gt;
				&lt;p&gt;
					&lt;form:label for=&quot;username&quot; path=&quot;username&quot;&gt;User Name&lt;/form:label&gt;
					&lt;br /&gt;
					&lt;form:input path=&quot;username&quot; readonly=&quot;true&quot; /&gt;
					&lt;font color=&quot;red&quot;&gt;&lt;form:errors path=&quot;username&quot; /&gt;
					&lt;/font&gt;
				&lt;/p&gt;
&lt;/fieldset&gt;
&lt;/div&gt;
&lt;pre&gt;