Dockerfile

Jekyll is based on ruby, so we build our image based on the ruby image.

FROM ruby
MAINTAINER eagle.xiao@gmail.com

Some gems requires a Javascript runtime, so we need to install node and python-pygments is required for syntax highlighting.

RUN apt-get update
RUN apt-get install -y node python-pygments

The jekyll gem. Bundler is required if you have your own Gemfile in the folder.

RUN gem install jekyll bundler

Map a folder from host to /src in the container and expose 4000

VOLUME /src
EXPOSE 4000

Setup working dir.

WORKDIR /src

Ideally, we should run bundle install first and then have the ENTRYPOINT to be ENTRYPOINT ["jekyll"]. I don’t know how to do it that way. (CMD?)

ENTRYPOINT bundle install && jekyll serve -H 0.0.0.0

Build the docker image

Change directory into where the Dockerfile is stored. Do not miss the “.” a the end.

docker build -t mrcoder/jekyll .

Clone theme

I use a theme forked from here. Simply clone it locally:

git clone https://github.com/mmistakes/hpstr-jekyll-theme.git

Run the Docker image

docker run --rm -v "$PWD:/src" -p 4000:4000 mrcoder/jekyll

If you are running it with boot2docker, you need to find out the ip of the docker host with boot2docker ip and open the site with http://ip-of-the-host:4000.

When I read the README of Flux, I found it difficult to get the point of the following section:

We originally set out to deal correctly with derived data: for example, we wanted to show an unread count for message threads while another view showed a list of threads, with the unread ones highlighted. This was difficult to handle with MVC — marking a single thread as read would update the thread model, and then also need to update the unread count model. These dependencies and cascading updates often occur in a large MVC application, leading to a tangled weave of data flow and unpredictable results.

Seriously, why it is “difficult to handle with MVC”?

While different people have different understand of the old MVC, the typical structure looks like V to C has a 1 to 1 map and M to V/C has a 1 to many map. It works so good if the structure make sense. What makes it difficult is actually when you want to have a 1 to 1 map for M to V/C and all the Ms needs a machanism to be kept synced.

Say, for example, we have only one model for the two views - “an unread count for message threads” and “a list of threads, with unread ones highlighted”. It is not SO difficult because when makring a single thread as read we can update the only one model, and it will not lead to “a tangled weave of data flow” or unpredictable results”.

Hmm, so why will one want to MAKE it difficult?

No, noboday want to make it difficult. Just by have two separate models for the two views make it a lot simple to understand. Yes, we just want to make it SIMPLE rather than DIFFICULT. In the following diagram, Controller disappears (sort of merged into View), Store is nothing more than Model.

However, we need a machanism to keep the two models synced. We have tones of ways to - create reference between each other, having another model refer to them, event-based synchorization, etc. We will discuss two options below.

Option 1: Refer to unreadCountModel from threadModel

Suppose there is not message bus (Dispatcher). The views listen to stores and stores listens to action creators. (Note, there other way to do so, for example update Views via Controller, but the point here is to show the complexity for populating changes across models).

// in threadModel
...
var unreadCountModel = unreadCountModel();

return {
    setAsRead: function(id) {
            _.forEach(threadArray, function(thread) {
                if (thread.id === id) {
                thread.read = true;
            }
        })
        updateUnreadCountModel();
    },
    updateUnreadCountModel: function () {
        var unreadCount = _.filter(threadArray, function(thread) {return !thread.read;}).size();
        unreadCountModel.setUnreadNumber(unreadCount);
    }
}
...

It is not SO difficult, but it would be more tricky if within setUnreadNumber, we need to update the threadModel - typical circel dependency problem.

Option 2: Dispatcher

Of course, we will spend some time explaining how Dispatcher can address this problem.

// in threadModel
onAction: function(action) {
    if (action.type === 'MARK_AS_READ') {
            _.forEach(threadArray, function(thread) {
                if (thread.id === action.payload.id) {
                thread.read = true;
            }
    }
}

// in unreadCountModel
onAction: function(action) {
    if (action.type === 'MARK_AS_READ') {
        unreadCount = _.filter(threadArray, function(thread) {return !thread.read;}).size();
    }
}

Conclusion

While we have been told that Model is stable than View, we have to acknowledge that some models are ViewModels. It is equally likely to change. Having a 1 to 1 map between Model and View makes more sense.

Technically speaking, Dispatcher is a singleton object which in OOD is a smell. However, I do not see a problem here. It just simplies the design. It works like a message bus and it should be a singleton, right?

[Not finished yet]

We will start with a gulp angular seeded project. Why an angular project? Because currently my team is using angular

1. Create the scaffold

yo gulp-angular

If you get the following error message: You don't seem to have a generator with the name gulp-angular installed, install the generator first with npm install -g generator-gulp-angular (note the generator- part). Again if you get another error: The package express does not satisfy its siblings' peerDependencies requirements!, replace -g with -G. I got it when I install with Gitbash on Windows, and haven’t verified on other operating systems. More information, please find this SO question. The error is not exactly the same by the way.

I chose Angular version 1.3.x, with no jQuery, no REST library ($http is enough), with UI Router, Bootstrap, Sass.

After generated the code, run

gulp serve

2. Inject react.js

bower install react --save

Now you have react.js on your home page.

3. Reactify JSX files

npm install reactify --save-dev

I have just published a blog on codepen. If you are an AngularJs developer and wonder if you should give ReactJs a try, check it out.

Mock has become so popular in agile development teams. Many disciplined teams won’t write a unit test without mocked dependencies. However, mock is not the silver-bullet. Instead, I find many teams using mock struggle with refactoring. Martin Fowler, Kent Beck and David David Heinemeier Hansson had a hangout last year, in which the shared their opinions on mocking.

The substantial problem of mocking is that when you set up the dependencies with mock, you are assuming an implementation, because you know that the mocked method will be called.

Martin Fowler, Kent Beck and David Heinemeier Hansson had a hangout talking about TDD, in which all three expressed their concerns around mocking from different angles. The videos last for more than one hour so here is the text version if you prefer. The hangout is not just about mocking. So I have attempted to summarise their concerns or comments on mocking below (extracted from the text version):

  • David Heinemeier Hansson does not agree with “isolated unit testing” because there tend to be “lots of mocks”.
  • Kent Beck doesn’t mock very much; implies it’s a smell of bad design.
  • Martin Fowler doesn’t mock much either.

DHH, Kent Beck and Martin Fowler did not use any code example in their hangout. I think some Java code can demonstrate the real problems better.

Let’s use online store as an example. To summarise the business rule, if an Order is shipped to within Australia, free shipping is applied, otherwise no free shipping.

Here is our test code:

@Test
public void free_shipping_applies_on_orders_shipped_within_australia(){
    Country mockedCountry = mock(Country.class);
    when(mockedCountry.getName()).thenReturn("Australia");

    Order order = new Order(mockedCountry, other, parameters);
    assertThat(order.freeShipping(), isTrue());
}

Here is our Order class under test:

public class Order {
    // other methods
    ......
    public boolean freeShipping() {
        return country.getName().equalsIgnoreCase("Australia");
    }
}

Now we would like to change the way to decide if the country is Australia from comparing Name to comparing Country Code.

public class Order {
    public boolean freeShipping() {
        return country.getCountryCode().equalsIgnoreCase("Au");
    }
}

The test will fail (throw NullPointerException), because getCountryCode is not mocked. We assumed that we will call getName, but that is an implementation detail. We are not changing the behaviour of the class Order. The test should pass without any change. If real Country object is used, it won’t fail. Yes, as you said, we should test contract. But we should test the contracts of the class that is under test, not how the class under test interacts with its dependencies, which is again implementation detail. A paper (www.jmock.org/oopsla2004.pdf ) published in 2004 suggested that we should “mock roles, not objects”. I agree that it is good technique to drive interfaces. It should be limited to that. It should not be used when the dependent classes are already there.

This is an elaborated example, but it does not mean the problems are there in rare cases. It is common and popular. I’ve seen more teams using Mock in most of the unit tests than not doing that. When they feel the pain of re factoring, they believe that is necessary pain. More teams do not feel the pain, because it has not hurt them that hard.

So I would like to reiterate the problems of mocking:

  1. Mocking is unfriendly to refactoring. The Mock-based test is highly coupled with the implementation.

  2. Mocking makes untestable (bad-designed) code look testable and gives fake confidence. Sometimes, especially when the object is quite complex, mocking an object is easier than creating a real object. That is a design smell(as Kent Beck said). It means your code violates either Single-Responsibility-Principle or Law of Demeter* or, in most cases, both. Before mocking your own classes, re-think if it is easy to create, build and configure. The team may lose an opportunity to verify the design, if they always go with mocking.

  • It is easy to understand, that when an object is difficult to create it may have too many dependencies and then tends to violate SRP. Another possible reason is it has a long dependency chain, thus difficult to create. In this case the code violates LoD.