Chariot Training Classes

Training Courses

I run Chariot's training and mentoring services. We provide training in AngularJS, HTML5, Spring, Hibernate, Maven, Scala, and more.

Chariot Education Services

Technology

Chariot Emerging Tech

Learn about upcoming technologies and trends from my colleagues at Chariot Solutions.

Resources

Chariot Conferences

Podcasts

Entries in Roo in Action (12)

Sunday
Aug212011

Now you can choose ActiveRecord or Service/Repo for Roo 1.2

Check it out!  Now you can install services and repositories, and when you scaffold the project automatically generates calls to the service layer rather than to the Active Record pattern.

I think personally it's a huge win for Roo to be able to support both approaches, since having to switch tools based on a difference in one pattern approach to me feels wrongheaded.  Here's a screenshot from IntelliJ:


The new service model in action with IntelliJHere is a snippet of the code written in the CourseController_Roo_Controller.aj file proving the nice integration:

privileged aspect CourseController_Roo_Controller {
  
  @Autowired
  CourseService CourseController.courseService;
  
  @RequestMapping(method = RequestMethod.POST)
  public String CourseController.create(@Valid Course course, 
       BindingResult bindingResult, Model uiModel, 
       HttpServletRequest httpServletRequest) {
    if (bindingResult.hasErrors()) {
        uiModel.addAttribute("course", course);
        return "courses/create";
    }
    uiModel.asMap().clear();
    courseService.saveCourse(course);
    return "redirect:/courses/" + 
         encodeUrlPathSegment(
            course.getId().toString(), httpServletRequest);
  }
  
  @RequestMapping(params = "form", method = RequestMethod.GET)
  public String CourseController.createForm(Model uiModel) {
      uiModel.addAttribute("course", new Course());
      return "courses/create";
  }
  
  @RequestMapping(value = "/{id}", method = RequestMethod.GET)
  public String CourseController.show(
      @PathVariable("id") Long id, Model uiModel) {
    uiModel.addAttribute("course", courseService.findCourse(id));
    uiModel.addAttribute("itemId", id);
    return "courses/show";
  } 
...
}

To try it out, head over to the nightly builds page and download the latest nightly.  (Do NOT unzip this over a working 1.1 or earlier 1.2 or you'll be crying a sweater of tears).  Then, make your /usr/bin/roo or /usr/bin/roo12 symbolic link (my angle as during the writing of the book I've been testing things against roo 1.1, 1.2, etc).  Create your project and you'll see the options.

You can build this if you put the snapshot repository into your list of repositories in your pom.xml file:

<repository>
    <id>spring-roo-internal-repo</id>
    <name>Spring Roo Internal Snapshot Repo</name>
    <url>http://spring-roo-repository.springsource.org/snapshot</url>
</repository>

Best of luck, and enjoy playing with the upcoming Roo features. I'm also going to check out some newer add-ons, such as JSF and the newly updated Flex (by Roo forum contributor working with the team on a patch) and GWT addons in future blog entries. For now, though, it's back to my add-ons chapter, which is coming soon.

Sunday
Jul172011

Testing Entity Validations with a Mock Entity - Roo in Action Corner

The following post is ancillary material from the upcoming book Spring Roo in Action, by Ken Rimple and Srini Penchikala, with Gordon Dickens. You can purchase the MEAP edition of the book, and participate in the author forum, at www.manning.com/rimple.

In Spring Roo in Action, Chapter 3, I discuss how Roo automatically executes the Bean Validators when persisting a live entity. However, when running unit tests, we don't have a live entity at all, nor do we have a Spring container - so how can we exercise the validation without actually hitting our Roo application and the database?

The answer is that we have to bootstrap the validation framework within the test ourselves. We can use the CourseDataOnDemand class's getNewTransientEntityName method to generate a valid, transient JPA entity. Then, we can:

  1. Mock static entity methods, such as findById, to bring back pre-fabricated class instances of your entity
  2. Initialize the validation engine, bootstrapping a JSR-303 bean validation framework engine, and perform validation on your entity
  3. Set any appropriate properties to apply to a particular test condition
  4. Initialize a test instance of the entity validator and assert the appropriate validation results are returned

The concept in action...

Given a Student entity with the following definition:


@RooEntity
@RooJavaBean
@RooToString
public class Student {
  
  @NotNull
  private String emergencyContactInfo;

  ...
}

The listing below shows a unit test method that ensures the NotNull validation fires against missing emergency contact information on the Student entity:

@Test
public void testStudentMissingEmergencyContactValidation() {
  // setup our test data
  StudentDataOnDemand dod = new StudentDataOnDemand();

  // tell the mock to expect this call 
  Student.findStudent(1L); 
  // tell the mocking API to expect a return from the prior call in the form of
  // a new student from the test data generator, dod
  AnnotationDrivenStaticEntityMockingControl.expectReturn(
     dod.getNewTransientStudent(0)); 

  // put our mock in playback mode
  AnnotationDrivenStaticEntityMockingControl.playback(); 

  // Setup the validator API in our unit test
  LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
  validator.afterPropertiesSet(); 

  // execute the call from the mock, set the emergency contact field
  // to an invalid value 
  Student student = Student.findStudent(1L);
  student.setEmergencyContactInfo(null);
  
  // execute validation, check for violations
  Set<ConstraintViolation<Student>> violations = 
    validator.validate(student, Default.class);

  // do we have one?
  Assert.assertEquals(1, violations.size());

  // now, check the constraint violations to check for our specific error
  ConstraintViolation<Student> violation = violations.iterator().next();
  
  // contains the right message?
  Assert.assertEquals("{javax.validation.constraints.NotNull.message}", 
    violation.getMessageTemplate());
   
  // from the right field?
  Assert.assertEquals("emergencyContactInfo", 
    violation.getPropertyPath().toString());
}

Analysis

The test starts with a declaration of a StudentOnDemand object, which we'll use to generate our test data. We'll get into the more advanced uses of the DataOnDemand Framework later in the chapter. For now, keep in mind that we can use this class to create an instance of an Entity, with randomly assigned, valid data. We then require that the test calls the Student.findStudent method, passing it a key of 1L. Next, we'll tell the entity mocking framework that the call should return a new transient Student instance. At this point, we've defined our static mocking behavior, so we'll put the mocking framework into playback mode.

Next, we issue the actual Student.findById(1L) call, this time storing the result as the member variable student. This call will trip the mock, which will return a new transient instance. We then set the emergencyContactInfo field to null, so that it becomes invalid, as it is annotated with a @NotNull annotation. Now we are ready to set up our bean validation framework.

We create a LocalValidatorFactoryBean instance, which will boot the Bean Validation Framework in the afterPropertiesSet() method, which is defined for any Spring Bean implementing InitializingBean. We must call this method ourselves, because Spring is not involved in our unit test. Now we're ready to run our validation and assert the proper behavior has occurred.

We call our validator's validate method, passing it the student instance and the standard Default validation group, which will trigger validation. We'll then check that we only have one validation failure, and that the message template for the error is the same as the one for the @NotNull validation. We also check to ensure that the field that caused the validation was our emergencyContactInfo field.

In our answer callback, we can launch the Bean Validation Framework, and execute the validate method against our entity. In this way, we can exercise our bean instance any way we want, and instead of persisting the entity, can perform the validation phase and exit gracefully.

Caveats...

There are a few things slightly wrong here. First of all, the Data on Demand classes actually use Spring to inject relationships to each other, which I've logged a bug against as ROO-2497. You can override the setup of the data on demand class and manually create the DoD of the referring one, which is fine. They have slated to work on this bug for Roo 1.2, so it should be fixed sometime in the next few months.

Also, realize that this is NOT easy to do, compared to writing an integration test. However, this test runs markedly faster. If you have some sophisticated logic that you've attached to a

@AssertTrue
annotation, this is the way to test it in isolation.

About this post

Did you find this post useful? Ken and Gordon both teach courses in Spring, Hibernate, Integration, Maven, Rails and more for Chariot Solutions. Visit our Education Services page for details on upcoming courses, including August's Hibernate with Spring.
Monday
Jan242011

Bug fix in 1 day?? WOW, ROO TEAM!

I wanted to give a shout out to the Roo dev team.  I put a feature request in to JIRA last week while I was working on good JUnit examples for Roo in Action, chapter 3.  I wanted to make sure the persistence context was cleared between persisting data and re-loading it, so that we could force the SQL statements to be called.  I had written that I'd like a entityName.clear() method, to match the entityName.flush() method.  

Literally ONE day later, Alan Stewart had the code for ROO-1989 added and committed to trunk.  I immediately updated the chapter document to add that feature to the list, and modified my test code.  WOW!

 

Tuesday
Jan112011

Roo in Action MEAP Update - RIA with Dojo, Spring MVC

We've just released a MEAP update for Spring Roo in Action.  The update includes a bevy of information about the Dojo framework, which is embedded in Spring Roo for all sorts of features, including client-side validations, those panel widgets, and drop-down date boxes.

I've struggled with putting information about other frameworks, such as jQuery, into the chapter.  For now, I've kept it to Dojo, and the server-side support for AJAX, to show the most expedient route to getting dynamic on the client side.  I also wanted to dig deeper into more advanced widgets like the tree control, etc., but then I'd be turning the book into a Dojo programming book.

I also have initial drafts of the GWT and Flex add-on sections, but since those add-ons aren't feature complete just yet, they are not documented in-depth.  They will be fleshed out in a later MEAP.

Let me know what you think on the Manning book forum.  I am glad to have moved this forward.

Tuesday
Dec282010

Debugging Roo Tiles Exceptions

This is a quickie.  If you're trying to debug Roo JSPX pages, on version 1.1.1 (or 1.1.0, I think) and you keep getting swallowed exceptions, with a generic "could not render page" error, just watch for uncaught exceptions on BasicTilesContainer, line 692.  The exception caught will have a cause, which explains what went wrong.

I will post a note on the forums - hopefully the Roo team can log this exception and make jspx debugging a little easier in a future release.

Ken