Kata for learning mockist/interaction/London style TDD in AngularJS
You will need node/npm and git installed.
You will also need Chrome (Firefox will work with a bit of configuration).
git clone https://github.com/zhon/wisdom-bot-kata-angular.git
cd wisdom-bot-kata-angular/
Grunt, karma and bower will be installed globally with the -g
flag:
npm -g install grunt-cli karma bower
The rest will be installed in the current directory by calling:
npm install
bower install
You will be editing src/app/chatroom/
To run the tests and the build
grunt watch
To view your work load wisdom-bot-kata-angular/build/index.html
into
your browser.
For more information take a look at the seed project
I hear you want to try Mockist style TDD. | I do! I do! |
What do you want to build? | A chat room with a wisdom bot in AngularJS. |
We start by writing an acceptance test. | Yes and for now they will be manual. |
Why not automate it? | I will, just not in this Kata. |
How do you test Hello World? | Manually by checking webpage build/index.html for "Hello". |
How would you write Hello World. | In Hello World! |
Should't "World" be a variable? | Sure! I can do that with simple scope binding:
Hello {{user}}!
.controller( 'ChatroomCtrl', function ( $scope ) {
$scope.user = 'World';
}) |
You didn't write a test and this is a TDD kata. | I don't write tests for simple scope bindings. They couldn't possibly break. |
How are we going to get the user? | The user will be entered in a form
<form>
<label>Name:</label>
<input ng-model="user" />
</form>
<hr/> |
We need to input our message. | We will just change the form a little to get both the user and message.
<form>
<label>Name:</label>
<input ng-model="message.user" />
<br />
<label>Message:</label>
<button type="submit">Send</button
</form>
<hr/> And to see it we will replace
<div class='chatbox'>
<ul>
<li>
<span class='user'>
{{message.user}}
</span>
<span class='message'>
{{message.text}}
</span>
</li>
</ul>
</div> |
With the UI for entering a name and a message, what shall we do next? | We will store the message (user and text) in a message repository. |
Great! And... | First I write the skeleton of an angular test. It starts with a
For This is followed by a Next we have another
describe('chatroomController', function () {
var scope ;
beforeEach(function () {
module("app.chatroom");
inject(function ( $rootScope,
$controller,
) {
});
});
describe('when a message is published it', function () {
it ('posts to MessageRepository', function () {
});
});
}); |
After template, then? | I fill in the test. It requires a mock. I will set that up in the
The test is simple: assert when This is what the whole file looks like:
describe('chatroomController', function () {
var scope, mockMessageRepository;
beforeEach(function () {
module("app.chatroom");
inject(function ( $rootScope,
$controller,
MessageRepository) {
scope = $rootScope.$new();
mockMessageRepository = sinon.stub(MessageRepository);
$controller("ChatroomCtrl", { $scope: scope });
});
});
describe('when a message is published it', function () {
it ('posts to MessageRepository', function () {
scope.message = {
'user': 'RedQueen',
'text': 'Off with her head!'
};
scope.publish();
expect(
mockMessageRepository.post.calledWith(scope.message)
).toBeTruthy();
});
});
}); |
I am getting an error when I run your test. | Yes, and that error is telling me to add method *Notice I put the
.service( 'MessageRepository', function () {
return {
post: function () {
}
}
}) |
Now when you run the test, what do you see? | An Error. It is telling me I need
.controller( 'ChatroomCtrl', function ( $scope ) {
$scope.publish = function () { };
}) |
Now what do you see when running the test? | I see a Failing test.Yes! Making it pass is easy. |
Hmm.. I look forward to seeing your code passing and checked in. | No problem! I will just add one line to the
$scope.publish = function () {
messageRepository.post(message);
} |
Are you ready to check in? | No. |
Why not? | Because I still need to acceptance test it. |
How will you do that? | I will load the web page (build.index.html ) in the browser and
see that message is saved. |
How? The message is not being stored. | I will add a
|
What happeded when you ran it? | Nothing. It isn't hooked up. I am hooking it up now by adding
<button type="submit" ng-click="publish()">Send</button> |
Now what do you see? | Both my manual and my automated test passing. |
It is time to check in aand grab a snack. | Mmm.... Snack! |