The Robot Factory Kata
On the drive home from my last Behavior Driven Development talk, I began thinking about the idea of Code Katas and how one might be appropriate in my future disucssions of Behavior Driven Development. Given that BDD tries to solve things in as simple and direct a path as possible, and given that BDD takes some of the lessons learned via TDD and applies them in slightly more business-centric language, a Kata would demonstrate well the effectiveness of BDD when applied to a problem domain.
So, I took the example problem domain of a robotic assembly line that I've been using since I was training full-time under the guidance of J. Michael Palermo IV and implemented it using SpecFlow and Moq. So far, the Robot Factory Kata video series has two videos.
The first of these demonstrates the project setup and configuration, and starts solving the problem using SpecFlow specifications and NUnit tests.
The second part helps demonstrate how mocking method verification using callback expectations to demonstrate testing interaction between two objects. Sure, this is getting into integration testing, but the idea is to demonstrate BDD using a legitimate problem domain that's slightly more interesting than the construction of a calculator. Not that there's anything wrong with that, but you know, it helps to have variety.
Hope you enjoy these video demonstrations and that they motivate you to start BDD'ing today.
5 Comments
Marcus Hammarberg said
Nice screen casts Brady.
I was not familiar with that Kata. Thanks!
I have a couple of things that I thought I'll add;
- you can have SpecFlow generate the stub code for you; on a step in your feature just hit F12 (Go to definition). This will take you to the step definition (if present) or open a dialog with the stub-code for the step definition. You can then chose to save it to the clipboard and then paste it into appropriate steps class file
- your asserts for "Given I have a robot" and "Given I have an assembly line" are asserting on the mock, not the object. Think you should use Assert.IsNotNull(_robot.Object);
- If your step definitions grow to more file than 1, you should consider storing state in ScenarioContext.Current instead of private field. See this: https://github.com/techtalk/SpecFlow/wiki/ScenarioContext.Current
I hope you find these suggestions helpful.
Thanks for sharing this post - great stuff. Looking forward to see the rest of the kata. :)
Sergey Berezovskiy said
Hi Brandy
What the point of testing mocks? Scenario is passing, but nothing is really done. Well, except Moq framework is tested.
Regards,
Sergey
bradygaster said
Sergey,
The purpose of mocks is to design the system abstractions and to provide a few "buckets of functionality," in the form of the interfaces designed to "mock" the system design. Once the system is designed in terms of the interface abstractions and the controller/orchestrator that uses those interfaces to "do the work," the interfaces can be implemented in real classes.
Reminds me, I need to write a second post for this guy that does exactly that - uses a controller/orchestrator to glue everything together.
Sergey Berezovskiy said
Brandy,
Waiting for your second post, maybe purpose of Mocks will be clear. I use mocks to replace dependencies of object being created. But here we don't have real object - only mocks, so I'm confused :)
BTW I think there should not be assertions on Given steps. It's the place where you actually create objects (or mocks).
Something like
public GivenIHaveARobot()
{
var robotMock = new Mock<IRobot>();
ScenarioContext.Current.Set<IRobot>(robotMock.Object);
}
Later you can get that info on When or Then steps
public WhenIAttachTheRobotToLine()
{
var robot = ScenarioContext.Current.Get<IRobot>();
var line = ScenarioContext.Current.Get<IAssemblyLine>();
line.Attach(robot);
}
bradygaster said
I didn't know that Sergey. That's awesome advice, I'll keep that in mind as I use and demonstrate SpecFlow. Thanks!