The Great Mock Debate continued
First, an apology to Alan:
Perryn’s right; by and large we agree. I should have phrased things better (again). That’s what I get for posting on Friday afternoon while trying to do three other things at the same time.
I know you know BDD. I just didn’t think you had covered it at all when saying, “No, no, no” to my insistence on using mocks, hence the rather lazily worded post. I should reword it as “he still only discusses testing in a context of ensuring that nothing’s broken”. Then, if you still find it irritating, it’s fair. Your experience far outstrips mine. I love to provoke, because it gets people riled enough to share their wisdom with me. Thank you for doing so.
Even so, assigning behaviour to people based on misconceptions or lazy thinking is far worse than doing it to code, and I do know better. Slapped wrist for me. Apologies to you.
Second, back to the point:
Maybe it’s because I type stupidly fast (not always a good thing, as evidenced above), but I find it a lot easier to just throw an interface in for something I haven’t designed yet, add methods as and when I need them and create a “real” class from it later. The alternative is to be writing two or three behaviour classes at once, trying to separate all the responsibilities for each, while mocking out the tools that they rely on or – heaven forbid – adding another couple of unfinished behaviour classes as the tools expand.
I wouldn’t use one behaviour class to test / design one class and its tools, because then anyone else who comes along to use the tools has no idea what they do. It’s a pain to have to track tools back and see how other classes are using them. So, if you need to have a behaviour class for each tool, why not just mock it out to start with?
The exception to this rule has got to be when you’re writing “utility” classes – pieces of the system which are going to be widely used, such as persistence layering, or in the case of my game stuff the asynchronous mechanisms. Then you’re designing a library which should be fully tested itself, and it seems just as reasonable to use these tools as it is to, say, create a new HashMap or ArrayList. However, using libraries brings its own fun and games – see Darren’s posts re third-party code. Even then, even for something as simple as file handling, I frequently want to use something other than the real tool so that I can either test what’s going in and out or stop it from affecting other tests.
And my final note (for this post, anyway):
The use of FooImpl for the implementation of interface Foo is really, really annoying me. Call it DefaultFoo if it really doesn’t do anything different to what it says on the tin, which I haven’t come across yet – most of the FooImpls here I would rename to ServicedFoo or similar. Calling something FooImpl implies that there will never be a different implementation of Foo. Mocks are an implementation of an interface too – they’re just very specialised.
Update: I’d only call them ServicedFoo because the relationships between the tools and the things which use them aren’t well defined (or designed), and having a better name is better than having the worst name, even if it’s still not great. This is called Technical Debt. I am working in a Technically Indebted environment which has matured to the point that the cost of change curve, whilst less steep than many of the projects I’ve been on, still exists. Unfortunately unwinding all of the tangled interrelationships, renaming poorly named classes, providing unit tests for everything etc. is so expensive that it no longer has any business value. I probably shouldn’t even suggest renaming things, because it’s not worth it. At least the bad naming is consistent. I’d just like to stop it happening in the first place.
(Is ServicedFoo really that bad? It implements Foo using server-side services… well, maybe I need more experience here.)
I do know that in an an ideal world, Foo is the relationship between the tool and the thing using it. Maybe the tool is actually called Bar.
An instance: I have a ReportEventHandler and RequestEventHandler interfaces. The thing which submits report events and handles request events is better known as the Engine, or back end. The thing which submits requests and handles reports is better known as the Gui. There’s a whole asynchronous event handling mechanism which sits between them which implements both interfaces. Neither the Gui nor the Engine needs to know about that, or even about each other.
Mocks and why you have to use them
Alan says you don’t have to use mocks for testing. “No, no, no!” he says. “If you never tested any collaborations with live objects, your rapid feedback test suite had limited use.”
That’s true; you don’t have to use mocks for testing – but try doing test / behaviour-driven design without them. It’s my fault; instead of writing “unit test or design” I should have put “unit test (read: design)”.
This is why I dislike the word test, though. As soon as the word test appears, everyone has a natural gravitation towards testing code after it’s been coded. Even though Alan is a very intelligent and imaginative developer who I know knows better than this, he still thinks instinctively of testing as being something which merely ensures that nothing’s broken. After all, you can’t test code before it’s been coded, can you?
Well, you can certainly write the test. The code will naturally follow – but this is why you have to mock out all the tools; because you haven’t got around to coding them yet. The functional or integration tests take care of the class interactions.
If you’re using JBehave’s StoryRunner to drive the functionality, then the functional tests (read: higher-level designs) all start out with mocks too!
More Context IoC
Thanks go to Ade for providing me with many fun links and this insightful comment:
public FootBallGame(RuleValidator rv, TimeKeeper tk, RuleEnforcer er, WhistleBlower wb, …)
you would have:
public FootBallGame(Referee r)
and the referee would then play all those roles.
More Inversion of Control
Followup to Darren’s post about Sam’s posts and my post. If you’re not interested in the detail, skip to the simple rules at the bottom.
Darren says:
GameFactory needs all that stuff is because it is presumably going to pass it down to the Game objects it creates. That is fine, and 5 parameters in a constructor isn’t setting off any code-smell alarms for me. I wouldn’t do it that way however. For a start, I question the need for a factory. Presumably somewhere there is a UI showing a list of possible games waiting for the player to choose one. I see no benefit in having an abstract factory when what I want to do in response to a user clicking ‘Tetris’ is a new TetrisGame(). The indirection of the factory is just getting in the way.If that were true, I’d do it that way too – but most of the time while I’m developing, what I actually want my factory to produce is a MockTetrisGame.
Darren says:
Timer is not what I would do. What the game object really wants is for something else to tell it when time has passed. Something external.With respect to the Timer class I mentioned, I hadn’t intended it to be a java.whatever.Timer, but an interface representing some timing mechanism. Bad naming; sorry. For a Tetris game, this would be the heartbeat which causes the shapes to fall, and is reset by the user moving the shape down. For a PacMan game, this would be the heartbeat which makes the ghosts move. In both cases this would be Mocked before it was ever implemented (at least, it would if you were doing TDD or BDD properly).
Yes; the game could have a TimeDependent interface – but it’s not really the Gamey main class or the GameFactory's responsibility to make the Game listen to the time. The Game responds to the user dropping the shape by asking the timer to reset. The timer, however, sends its events not to the game but to an event thread, so that you don’t get the slightly ugly situation in which a user presses “down” only to find that the timer’s “down” happens first, causing the shape to drop two spaces when you only wanted it to drop by one.
Oh, bother. I forgot to put the event mechanism in the constructor. Now I have to change all those constructors again…
Darren says:
Scorer. The game could expose a public TetrisScore basicScore() method, that a collaborator can call, and do its own post-processing on before showing it to the user.Making the game responsible for calculating the score results in far too much code in the game. It isn’t the game’s responsibility to know that each line completed and removed is worth 10 points. So I created a Scorer class, which can listen to game events and make up its own mind about how many points to give to the user. Now I can decide to weight the score based on the size of the game board, and the Game doesn’t need to know about it.
Behaviour Driven Design is all about responsibilities, and thinking about how something ought to behave. I’ve used games as an example because everyone’s played them, and they’re very easy to visualize, but a little imagination should allow you to see how the complexities of a simple game could multiply for something like, say, a retail till application.
Anyway, here are some simple rules which I try to follow when coding:
- New objects shouldn’t be created outside of the
mainmethod or factories.
You could create a helper class to take care of some of the responsibilities of a class that’s grown too big, it’s true – but how are you going to decide what responsibilities fall to each of the two classes without separate behaviour classes (commonly called “tests”) for each? To truly unit test or design a class, you have to mock out all of its tools. It also allows the tools to be configurable, like theScorerabove. - Tell, don’t ask.
Unless the purpose of the tool is to reveal information (eg: a filereader) it should know how to use the information it’s got. Don’t look at the space between the hammer and the nail and try to judge how far you’ve got left to go for the optimum hammer strike. Just hit the nail with the hammer, and trust that the two of them will work it out somehow.
Mygetphobia is why I don’t like the idea of havinggetmethods on a context or toolbox. I can’t think of a better way of doing it yet, but will keep thinking on it until I do. - Keep your gui and your engine separate.
I shouldn’t have to write that one down. More importantly, though – keep the events in separate threads. Your gui shouldn’t hang just because the back end is busy doing something. Similarly with any system which has a responsive public face and processing behind the scenes. - Try not to add functionality to a class.
If you didn’t put some piece of functionality into a class when you first designed its behaviour, there’s a good chance that it’s not really responsible for the behaviour you’re about to add. Consider providing it with a separate tool to carry out a task, or pushing the functionality down into components which have the information to deal with the problem.
I’ve picked up rules 1, 2 and 3 from elsewhere (1 and 2 quite recently). Will try to add links.
Rule 4 is my own, from bitter-sweet experience.
A slightly different approach to Context IoC
I read Sam’s post on Contextl IoC, questioning its benefits. I’ve been skirting around this kind of thing for a while. I like the idea of being able to package all the things which a class needs in a box which ‘belongs’ to it.
Say my main class, Gamey, knows how to start new Tetris games.
It needs a game factory which creates games.
The game factory needs to know about user preferences, the gui components to be used to draw the game, the score system, the rules, the timer which drops the shapes, the factory which makes the shapes, etc.
So I need to construct the GameFactory as:
new GameFactory(UserPreference preference, GuiComponentFactory factory, Scorer scorer, RulesEngine rulesEngine, Timer timer).
and ditto for the game it creates.
Except that what I really want is to be able to create different kinds of games, so I can choose to play either Tetris or PacMan, and use a different game factory for each one. They still each need the same stuff – a component factory, a preference, a scorer, a rules engine, a timer etc – so now I have to duplicate that factory constructor for both types of factory; the TetrisGameFactory and the PacmanGameFactory.
Now I want to add multiplayer support, so that each monster killed appears in another person’s game, or each line deleted causes extra blocks to appear elsewhere. Now I need to add MultiplayerSupport to:
- Two GameFactory constructors
- Two Game constructors
- The calls for Game construction
- probably some abstract stuff in some
AbstractGameFactory, and someAbstractGame, etc.
And I don’t even know, in the GameFactory, which bits are related to the Game and which bits are being passed further down, to the Game’s pieces, like the Tetris shapes and the Pacman ghosts, which are also factory-driven but which need to be created by type. Oops, forgot the PiecesFactory. That’s another change, then.
I really like the concept of a Game.Context and a Shape.Context and a Tetris.Context and a Gamey.Context. They can even extend each other or contain each other if required – for instance, the Tetris.Context extends a Game.Context, and contains a ShapeFactory which needs a Shape.Context. Then, when I want to change a dependency, all I need to do is change one context and its construction. I don’t need to pass it through all the layers, abstract and otherwise.
This solves a real problem I’ve been coming across when trying to do behaviour driven design. I don’t want to have to think about the behaviour of my shapes when I’m still thinking about the responsibilities of my games. If I can give the game an empty Game.Context to start with and never worry about how the GameFactory constructs the Game again, then that’s one less piece of code to change every time I decide to add a bit of functionality.
The Game.Context shouldn’t be responsible for using the Game’s tools for it, though. It’s just a little container; nothing else. It should probably just have get methods (ugly, but suggestions welcome; will think on it) for each of the tools it requires.
I’m not even sure that the Game.Context needs to be an interface. It never needs to be mocked – you mock the tools underneath, not the container.
Stacy reckons there has to be another way to prevent the duplication which keeps cropping up in my normal dependency injected code. I also reckon ‘context’ is a poor name; ‘toolbox’ might be better.
The continuing saga of Windows vs. Linux
My Windows partition on my PC fell over last night; not sure why. Might have been something I did whilst trying to mount it (read-only, always read-only) in Ubuntu. Or it could just be sulking because I didn’t put the Windows CD back in for the reboot.
“No problem,” think I. “I’ll just reinstall Windows and put GRUB back manually.”
One corrupted boot sector later, I found myself digging around in my old floppies, trying to find something – anything – which could make the hard drive even usable. I ended up using fdisk off an old Windows 95 floppy. Telling it that I didn’t want large disk support (were small disks really that small?!) did the job, though I’ve lost all the data on the drive (luckily just a few days’ email).
I have now decided to install Ubuntu and Windows on separate hard drives, like two fractious siblings that can’t be left in the same room together.
Shiny new toys
My shuttle box for my new server arrived this morning, along with some wireless router stuff and my laptop mouse.
Why is it that owning shiny new toys always makes me want to buy more shiny new toys? I have an overwhelming urge to browse Overclockers, even though I did that only last week. I’ve already bought every single piece of electronics that I can remotely justify, and a few that were just plain excessive.
Retail therapy is such fleeting bliss.
Opportunity and how to grab it
If I want to make a fire, I need a little more than just a spark. Something combustible is usually important, otherwise, when that spark happens, I won’t be in a position to build it into a fire. Opportunity’s the same; if I’m ready for it, then I’m in a position to make the most of it. This readiness is something which most ‘lucky’ people have in common.
“Chance favours the prepared mind” – Louis Pasteur
Sometimes, though, there is no spark. There are two ways in which I can deal with this problem: either I can go where a spark is, or I can work at making one. I can draw on the experience of others where appropriate – perhaps they know where a suitable pair of stones can be found – and I can get them to help me, if they happen to have a lighter on them.
But what should I do if I’m stranded on a desert island, with no flint and steel, no lighter and no magnifying glass?
Time is an opportunity. I shall find bits of wood and rub them together in different configurations until I work out how to make fire.
Time is the most precious of all opportunities. Everyone wishes there was more of it in the day. I drink far too much coffee because I never give myself enough time to sleep in. Other people struggle to find time with their kids, time for their hobbies, time to get their work done, time to breathe.
If there’s really nothing I need to get done with my time, I can prepare for when I will need it. I can refactor code. Learn new things. Tidy my desk. Tidy my brain. Get that boring task that I’ve been putting off for weeks out of the way. Talk to people and find out what’s happening. Eat sensibly. Go to the gym.
Whatever I do – I must not just sit down in front of the TV. That way lies ill-fortune. Every hour I spend watching Eastenders is an hour of my life that I can never get back.
The Great Debian Experiment
This weekend, I have been mostly trying to make Debian work on my PC.
I should have realised that something was wrong when my boot sector virus scanner picked up LILO as an enemy (it seemed fine with GRUB before). Nine CDs later I logged in. The CDs don’t seem to support my graphics card, or my network card. So no Gnome or X-Windows, and no easy way of updating them. (I tried several installations with different graphics configurations and no success).
I eventually figured that the best thing to do would be to get connected, then apt-get in any updates. I have a Linux network driver. Unfortunately it didn’t like my setup and requested the kernel source so that it could compile an interface for itself. Debian does come with kernel sources, but none of them seem to match the default installation. So I found one of the others and learnt how to compile a new Linux kernel. In that respect, the Debian experiment was a great success; it taught me a lot about Linux and how it works.
Getting my network driver out of its zip on the backup CD was also a mission. I’m afraid I resorted to the use of my Windows partition. Note to self: when backing up Linux stuff, use tar.
The network driver needed another module as well as the source. No idea where the module can be found. I spent 20 minutes looking for this information. Eventually sanity dropped in to point out that I was on the path that leads to the zoo and the shaving of the yak.
20 minutes after that I had Ubuntu up and running, with Gnome at 1280 x 1024, full connection to my LAN and the internet, and my email restored to its usual place.
I hereby apologise to the gods of Ubuntu. I’m sorry that I ever doubted you. Appropriate sacrifices will be made on the altars of chaos next time I play nethack.
After Ubuntu
My experiments with running Ubuntu Linux have mostly been successful. I’ve certainly learnt a lot about Linux. I love the Debian package management system, and both the Gnome and KDE desktops are great (though anyone thinking of installing KDE be warned: KBounce is mindlessly addictive).
Ubuntu doesn’t feel very mature, though. For instance, last time I upgraded XMMS (a Winamp-like MP3 player) it stopped working under Gnome, though it still works fine under KDE. I still haven’t got my Palm and GPilot / JPilot working properly. Occasionally the entire desktop hangs. I’m sure that at some time in the future Ubuntu will be perfect for newbie Linux users who don’t want to tinker, but at the moment it’s just a little frustrating for those of us who do. It’s impossible to tell whether it’s my setup or Ubuntu itself that’s falling over.
So – I’m ready to move on. Thanks my newly acquired super-broadband-powers, I am downloading the seven CDs required for Debian. I am going to make myself a little media / document server in a Shuttle box (I’ve always wanted one), and reinstall my big tower so that it’s nice and clean. This time round I am not relying on the forums. I have bought a couple of books to help me with the installation.
This is an arbitrary list of strange words and concepts which I’ve come across, so that I remember what I’m doing:
- dyndns : Dynamic hosting. There are some sites around which let you do this for free. With the appropriate setup, you can ssh through the router and into the server on the other side.
- ssh: Not a new concept, but something I’ve never really got to grips with. I have a private key for the first time so that I can commit on the JBehave project.
- LAN: A local network, like the one we have at home. It was set up by a previous lodger. I want to understand this weird creature.
- Wireless: I’m aware that there are some security issues with wireless networks. I need to investigate.
- WINE: Wine Is Not an Emulator. It sits on top of Linux and provides Windows APIs. Microsoft Office already works on WINE. All I need to do is get DataViz’s “DocsToGo” working along with the Palm software, then maybe a couple of games like Doom3, and I will never need to use Windows at home again.

Comments