Trifork Blog

Posts by Tom van Zummeren

Twitter

Developing apps for the Pebble smart watch

June 18th, 2013 by
(http://blog.trifork.com/2013/06/18/developing-apps-for-the-pebble-smart-watch/)

Pebble

In this blog I want to talk about Pebble. A watch that can connect to your smart phone (both iPhone and Android) via Bluetooth to do all sorts of cool stuff a regular watch can’t do. Among the cool things you can do with it is install apps, which you can write yourself. As a geek and iPhone owner, I find this possibility especially interesting! I want to give an impression of what Pebble is, what it can do and how you can get started developing apps for this watch!

Read the rest of this entry »

Apple WWDC Keynote 2013 - My opinion

June 12th, 2013 by
(http://blog.trifork.com/2013/06/12/apple-wwdc-keynote-2013-my-opinion/)

AppleIf you haven't already you should all watch Apple’s WWDC keynote that was streamed live from San Francisco earlier this week; some really interesting things were announced. At least that’s how I see it and in this blog entry I'll give you my thoughts on some of my highlights, but there were so many small things they covered which you really have to see (or experience) instead of reading about it. Anyway, if you don't want to watch the 2-hour keynote, then this blog entry provides you with a good alternative...

Read the rest of this entry »

Properly testing Spring MVC controllers

December 11th, 2012 by
(http://blog.trifork.com/2012/12/11/properly-testing-spring-mvc-controllers/)

In this post I want to introduce you to the Spring MVC testing framework, a way to properly test your Spring MVC controllers.

The way I used to do it

I have always found unit testing Spring MVC controllers nearly useless because I felt they don't test anything useful for the most part. If something would break in the implementation, those unit tests would rarely fail. To explain what I mean by this, let me give you an example. Say you want to unit test the following controller method:

@RequestMapping(value = "/people/{groep}", method = RequestMethod.GET)
public String listPeopleInGroup(@PathVariable String group, ModelMap modelMap) {
    List<Person> people = peopleService.listPeople(group);
    modelMap.put("people", people);
    return "peopleList";
}

All this controller method does is take the "group" parameter from the URL and list all people who are in that group. But it has a bug in it I didn't notice. Usually you would unit test this controller by just mocking the peopleService using EasyMock or Mockito, pass in a fake Model and off you go! This is what the unit test in that case typically would look like (using JUnit, Mockito and Hamcrest):

public class PeopleControllerTest {

    @InjectMocks
    PeopleController controller;

    @Mock
    PeopleService mockPeopleService;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testListPeopleInGroup() {
        List<Person> expectedPeople = asList(new Person());
        when(mockPeopleService.listPeople("group")).thenReturn(expectedPeople);

        ModelMap modelMap = new ModelMap();
        String viewName = controller.listPeopleInGroup("group", modelMap);

        assertEquals("peopleList", viewName);
        assertThat(modelMap, hasEntry("people", (Object) expectedPeople));
    }
}

Let's run this unit test ...


Green light! Wow that's amazing, this controller works like a charm! But oh wait, let me try to run this in a browser now.

What did we test?

Hmm, ok something obviously went wrong here. Why did the unit test not cover this? Well, as I mentioned before: it's useless! Because what did it test exactly?

  • A call to the peopleService is made
  • The return value from the peopleService is put inside the ModelMap
  • The correct view name is returned

What didn't we test?

Some examples of things the unit test didn't cover:

  • That it responds to the correct url
  • That the PathVariable correctly takes the value from the "{group}" part in the url
  • That the method accepts GET requests
  • That any class-level annotations are also working as you expect
  • That any handler interceptors are called before and/or after executing this method
  • That any other methods in the controller are called beforehand, like those
    annotated with @ModelAttribute or @InitBinder.
  • That binding from parameters to an object works the way you expect
  • That any validation errors were registered by validators

Introducing the Spring MVC test framework

Recently a colleague of mine pointed me towards a little framework created as part of the Spring Framework called spring-test-mvc. This framework makes unit testing controllers a lot more meaningful! It actually has the ability to test all the aspects of a controller method I couldn't test before. Let's see if I can reproduce the above bug using Spring Test MVC.

public class PeopleControllerTest {

    @InjectMocks
    PeopleController controller;

    @Mock
    PeopleService mockPeopleService;

    @Mock
    View mockView;

    MockMvc mockMvc;

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mockMvc = standaloneSetup(controller)
                .setSingleView(mockView)
                .build();
    }

    @Test
    public void testListPeopleInGroup() throws Exception {
        List<Person> expectedPeople = asList(new Person());
        when(mockPeopleService.listPeople("someGroup")).thenReturn(expectedPeople);

        mockMvc.perform(get("/people/someGroup"))
                .andExpect(status().isOk())
                .andExpect(model().attribute("people", expectedPeople))
                .andExpect(view().name("peopleList"));
    }
}

The above unit test almost needs no explanation. It reads like reading a book. We perform a get request, check if the status is OK (status 200), check if a model attribute exists named "people" and check if the view name is "peopleList". Now let's run this unit test ...

Yes we did it! We are now essentially seeing the same error message as we saw in the browser. So what mistake could I have made in my controller method that a 'normal' unit test failed to cover? Let's take another quick look at the code.

@RequestMapping(value = "/people/{groep}", method = RequestMethod.GET)
public String listPeopleInGroup(@PathVariable String group, ModelMap modelMap)

Oh yes, of course! I made a typo in the path variable inside the url string. Of course "groep" doesn't match the method argument named "group" so the request fails. Let's correct my mistake.

@RequestMapping(value = "/people/{group}", method = RequestMethod.GET)
public String listPeopleInGroup(@PathVariable String group, ModelMap modelMap)

Run it again ...

This proves my point. A unit test written using Spring Test MVC closely resembles a real request made by a browser. That's why this test is a lot more meaningful. The fact that this test is now passing makes it very likely that it will work in a browser as well. The fact that the other unit test passed, didn't tell us anything.

Testing a REST interface

Spring Test MVC is especially useful when building a REST interface which for example returns JSON responses. The framework contains all sorts of stuff for easily building a test request and carefully examining the response.

Let's say we have a controller that listens to the URL "/people" and adds a person to the database whenever a POST request was received on that URL. The request body would be a JSON representation of the person to add. The response body will hold JSON that tells us what the database identifier of the person is that was just added, and also gives us a list of all people that have been added so far. This is how you would test this:

mockMvc.perform(post("/people")
        .contentType(MediaType.APPLICATION_JSON)
        .body("{\"firstName\":\"Tom\", \"lastName\":\"van Zummeren\"}".getBytes()))
        .andExpect(status().isCreated())
        .andExpect(jsonPath("$.identifier", equalTo("123")))
        .andExpect(jsonPath("$.allPeople[*].firstName", hasItem("Tom")));

verify(mockPeopleService).persistPerson(new Person("Tom", "van Zummeren"));

In this example we see a few new things. The content type is set on the request, a request body is given, and the response is checked using an expression language provided by the "json-path" framework.

This test tests so many things now. It's not just calling the controller method, it's also testing:

  • The mapping of the request body to a Person object
  • The status code that was set on the response
  • That it supports the given content type
  • That it listens to a POST on the /people URL
  • The mapping of the response object is transformed correctly to JSON

Conclusion

Spring Test MVC is indispensable if you want to test your Spring MVC controllers. Simply testing the controller methods without including the Spring MVC framework itself, is useless. Spring Test MVC will be included in the Spring 3.2 release (so I'm told) but for now it can be found on Github: https://github.com/SpringSource/spring-test-mvc

Tech Meeting on November 1st will be all about iOS!

October 19th, 2012 by
(http://blog.trifork.com/2012/10/19/tech-meeting-on-november-1st-will-be-all-about-ios/)

Next tech meeting isn't about anything related to Java, but it is targeted towards Java developers. Together with my uncle Jos Jong I will first give you all a brief introduction to Objective C and iOS and compare it a little to Java. Also we will try to convince you that Objective C is a cool language worth looking into and playing around with! I will even give you a live coding demo of creating an app from scratch. Hopefully you will get inspired to start creating an app yourself!

After the pizza & beer break we will go into more detail about the iPhone app we developed together called Easy Calendar. This app was released in the first quarter of 2011. We will tell you all about how the app evolved into what it is today. We will cover the experiences we've had with developing, marketing and creating the graphical design for the app. Also, we will tell you about how we dealt with the bigger display which comes with the new iPhone 5.

If you're interested, you can sign up here (don't worry, it's free!): http://info.orange11.nl/Nov2012mobiletechmeeting.html Hopefully we'll see you all there!

Tom van Zummeren
Jos Jong

Learn to write with Tracy

April 26th, 2012 by
(http://blog.trifork.com/2012/04/26/learn-to-write-with-tracy-ipad-app/)

I am very proud to announce Orange11's first iPad application: Learn to write with Tracy (dutch: Leren Schrijven met Tracy) which has just been released world wide in both Dutch and English. I personally developed this app from scratch with the help of my colleague Dennis de Graaf for the graphical design work. I thought this would be a great opportunity to tell you a little bit what the app is all about and a sneak behind the scenes as to how it was made.
Read the rest of this entry »

AppCode: IntelliJ for Objective C!

July 6th, 2011 by
(http://blog.trifork.com/2011/07/06/appcode-intellij-for-objective-c/)

AppCode logoWhen I started writing my first iPhone app, I was quite disappointed with XCode. This is because I have been using IntelliJ for the past five years, which I love working with ever since I first started using it. XCode is the IDE you have to use in order to develop iOS and Mac apps. Until recently there weren't any real alternatives.

Compared to IntelliJ, XCode looks very basic to me because it has no handy shortcuts, good refactoring tools or other handy features that I'm used to in IntelliJ. XCode doesn't look like a software tool that's developed by Apple at all. It is clear Steve Jobs was not involved creating this tool.

After I came to the conclusion I was probably just spoiled by IntelliJ, I accepted the fact that XCode wasn't as good. Furthermore, I was learning a new language and had to accept that I'm in a different world now. Recently XCode 4 was released, which admittedly has improved a lot compared to XCode 3. But, as I found out, XCode 4 still needs to come a long way to even come close to the usability of IntelliJ.
Read the rest of this entry »

Developing apps compatible with all iOS devices

November 25th, 2010 by
(http://blog.trifork.com/2010/11/25/developing-apps-compatible-with-all-ios-devices/)

As you might already know, iOS is the operating system that runs on iPhones, iPod Touches and iPads. The first iOS device was the iPhone and was released in January, 2007. Back then the operating system was called "iPhone OS". Since that time more devices were released running iPhone OS than just the iPhone. This is why a while ago Apple announced that the operating system would from that point on be called "iOS" instead.

When you’re developing an app for iOS you most probably are focusing on just one specific device with a specific version of the operating system. For example you’re developing for iPhones running iOS 4.2. If your only target audience is iPhone users then this is good enough. But you could make you’re app support other devices and iOS versions as well. This would extend the target audience for your app. As it turns out, it isn't much of a hassle to do so!
Read the rest of this entry »

iPhone OS 4.0

April 11th, 2010 by
(http://blog.trifork.com/2010/04/11/iphone-os-4-0/)

This is just a quick blog post to share my excitement for the new iPhone OS firmware version 4.0, which was announced by Apple just a few days ago. Yesterday I installed the beta version of this new OS on my phone, only to find out that a few of the new features are not supported on iPhone 3G :( Unfortunately, those features will be available only on iPhone 3GS. Nonetheless, I am very excited about all this new stuff and want to go over the most interesting features, both from a user’s and a developer’s perspective.
Read the rest of this entry »

Free Java hosting with the Google App Engine

February 4th, 2010 by
(http://blog.trifork.com/2010/02/04/free-java-hosting-with-the-google-app-engine/)

Lately I have been looking into and playing around with the Google App Engine. In this post I want to give a little introduction to the Google App Engine, why it can be interesting and how to work with it.
Read the rest of this entry »

Exploring the world of Android :: Part 3

October 8th, 2009 by
(http://blog.trifork.com/2009/10/08/exploring-the-world-of-android-part-3/)

In my travels through the world of Android I faced a lot of challenges. Brave as I am, *cough* I conquered each one of them. A few of the challenges include saving activity state, asynchronous tasks, pagination, error handling, context/option menu's and even drawing custom application/tab icons in Photoshop! Some challenges I already shared with you guys, but there is one challenge in particular I would like to elaborate on this time.

The app I am currently building is getting larger every day, and so is the main Activity class! Because my main activity contains a TabHost with a bunch of tabs, it also contains references to all individual view components contained in those tabs. All kinds of listeners are registered on those components so the activity contains some inner and anonymous classes as well. So you could say that this activity now has way too much responsibility! What I was looking for, is a way to separate the main activity into multiple parts, each with its own clear responsibility.

As it turns out, you can create custom components for a single piece of functionality within an Activity. Exactly what I was looking for!
Read the rest of this entry »