TDDing an Interface - a Twitter influenced discussion 49

Posted by Brett Schuchert on 6/8/2009

Background

I’ve collected a few quick notes regarding TDD and interfaces (as in Java/C# or C++ classes with all pure virtual methods). You dynamic-language-using-types (near irony intentional) can read and laugh to yourselves! You don’t need stinking interfaces, right?

Note, these are based on a few questions from someone I follow on twitter. I considered leaving out the original poster, but since it’s on twitter, I guess that’s not really going to stay hidden. And, quite frankly, his questions are pretty good and quite common.

I’m interested in seeing what other people have to say about this.

Here’s the original question from @GBGames:
When TDDing, I see info on using interfaces, but how do interfaces get created through TDD? How do you unit test your way to an interface?

Interfaces and TDD

There are several reasons an interface comes up while practicing TDD, here are two:
  • You have some existing code that has a concrete dependency on something and you want to remove that relationship.
  • You are working on new production code, taking a mockist approach and you want to create an object, inject dependencies represented by test-doubles that implement interfaces that do not yet exist.

@GBGames goes on to write (remember, this was in Twitter, so I left the abbreviations and such as is):

Game uses HardwareLayer. HL used libSDL but don’t need SDL for unit tests so I wanted IHL for a mockHL. But how to get IHL? Most info I find assumes interface exists or class exists to extract interface. I feel like I’m trying to do 2 things at once.

This additional information suggests something like the following:

@GBGames suggests using an IHardwareLayer to fully get rid of libSDL, which is a fine approach. Another approach is testing the HardwareLayer directly (with unit tests on the HardwareLayer) and passing in an adapter to libSDL (basically an ILibSdl):

What are we Testing?

If the goal is to test responsibility/functionality that belongs in the Game, then creating the IHardwareLayer is the right thing to do. The game only cares about the hardware layer and not the libSDL. If the goal is to test responsibility/functionality that belongs to the Hardware Layer, then that’s where we should start. However, this decision is academic. Why? @GBGames’s original question was, in a nutshell:
When using TDD to test a class that depends on an interface that does not yet exist, how do you go about doing that?
He observed, correctly, that it seems like you are doing two things at the same time, and you are:
  • What methods exist in the interface
  • How will the class under test use that interface.
So how to proceed? Here’s an example I posted a little while back that demonstrates the use of Mockito. My original intent was to demonstrate Mockito. However, that example also shows how, over a series of tests, I:
  • Create interfaces
  • Add methods to those interfaces needed to add functionality
  • Set expectations on the use of those interfaces
There are a few important points from the original question:
  • The Hardware layer, apparently, does not yet exist.
  • By extension, the interface does not yet exist.
  • When writing the real hardware layer class, it will ultimately have to implement all of the methods in the interface created while TDDing the game class
  • Writing the actual hardware layer class will require TDDing it, and passing in an ILibSDL class. This is not strictly necessary, but if you want to test the HardwareLayer without using the real lib SDL, that’s your best option.

Now to get more concrete

So let’s assume that in fact we are starting from scratch on a game and we want to develop it without requiring a real hardware layer. Is it reasonable to assume the use of a hardware layer before we’ve even started writing the game? I say yes. What do you say? So I’d need to come up with some tests (test categories) to get started (I’m just making this up, I don’t have any idea what GBGames is actually working on right now):
  • Creating a game properly initializes the hardware layer
  • Creating a game properly acquires some kind of game configuration information, which is used to configure the hardware layer (e.g., preferred resolution, color depth, anti-aliasing, ...) (Do you see that even these two test categories actually suggest more than just two classes if you consider the single responsibility principle.)

This is enough to start to express my intent. Almost time to start with something.

One final set of questions before I get really started:
  • One assertion per test?
  • TDD or BDD (At the very lest, looks like we’re staring outside in)
  • ...

Test 1: Initializing

How about when I create a game, I want to make sure that it sends some basic initialization to the HardwareLayer:
package com.om.example.gameandhw;

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

import org.junit.Test;

public class GameTest {
  @Test
  public void itShouldInitializeHardwareLayerDringGameConstruction() {
    IHardwareLayer layer = mock(IHardwareLayer.class);
    new Game(layer);
    verify(layer, times(1)).setResolution(1024, 768);
    verify(layer, times(1)).setColorDepth(8);
  }
}
Note that this is the final test. I had to stop on each of the four lines:
  • On the first line, I had to create and interface IHardwareLayer, no methods.
  • On the first line, I also had to stop to statically import the mock method.
  • On the second line I had to stop and create the Game class.
  • On the second line I had to stop and add a constructor with a parameter (the injected IHardwareLayer, for which I use the Mockito library to create a test-double, which I am using as a Spy)
  • On the third line I had to stop to add the method setResolution to the IHardwareLayer interface.
  • On the third line I had to stop to add the static import of the verify method.
  • On the fourth line I had to stop to add the setColorDepth method to the IHardwareLayer interface.

(Trust me, it too much longer to type that list than to do the work. The actual work was well under 30 seconds to do all of that.)

After this test compiled, but did not pass, I had to write the method for Game. Here are the other two java files I created as a result of this single test (getting the test to pass the first time was included in that 30 seconds above):
package com.om.example.gameandhw;

public interface IHardwareLayer {
  void setResolution(int widthInBits, int heightInBits);
  void setColorDepth(int bitsPerChannel);
}
package com.om.example.gameandhw;

public class Game {
  public Game(IHardwareLayer layer) {
    layer.setResolution(1024, 768);
    layer.setColorDepth(8);
  }
}

Now I have no idea if this is even beginning to make any sense for the original problem. This is where having a pair partner with expertise on the game requirements (and maybe some idea about this libSDL) would greatly help.

Notice, however, that as I try to write the Game class, I am adding methods to the IHardwareLayer class AND figuring out how the game will interact with those methods.

Hope this helps GBGames. I also hope to see some discussion in the comments section.

Brett

Comments

Leave a response

  1. Avatar
    Steve Freeman about 8 hours later:
    Some comments:
    • passing the layer into the Game constructor when it isn’t held onto feels odd. Is there more to come?
    • IHardwareLayer isn’t really a role, it describes an implementation structure. Is this, perhaps, a Display?

    I know this sounds picky, but these are the sort of questions that we’ve found forces our code into making sense.

  2. Avatar
    Steve Freeman about 8 hours later:
    Some comments:
    • passing the layer into the Game constructor when it isn’t held onto feels odd. Is there more to come?
    • IHardwareLayer isn’t really a role, it describes an implementation structure. Is this, perhaps, a Display?

    I know this sounds picky, but these are the sort of questions that we’ve found forces our code into making sense.

  3. Avatar
    Brett L. Schuchert about 10 hours later:

    Is there more to come? In the real system, I’m sure there will be, for this example, I don’t see the need.

    As for passing in the IHardwareLayer, what would you recommend instead? A factory of some kind? The one thing I would not do, of course, is make the game responsible for creating the hardware layer. There are many forms of Dependency Injection. I happened to pick using the constructor. In reality, having a configurable factory might make more sense. And when there’s enough code to push that change into the system, I’d consider it.

    I do not understand how you are using the idea of a role. Role as in an employee has one to many roles? If so, how does anything in this solution suggest that? This looks closer to the bridge pattern to me (though it’s not quite that).

    The name comes from the original domain expert, GBGames. Until there’s more tests, and the interface is somewhat more filled out, I’m not sure what to call it. I do agree that it might be somewhat solution driving tests but I don’t see that as a problem.

  4. Avatar
    justin davies 1 day later:

    Great stuff Brett, very interesting. I found it hard to pick up mocking interfaces as a design starting point when beginning TDD and I can imagine others experiencing the same. The method you’ve illustrated is definitely the way to go. I found my groove when moving to context specifications as for me it makes the process more expressive – I’ve put something together that illustrates the above code using context specifications: http://www.beingnew.net/2009/06/driving-design-of-interfaces.html

  5. Avatar
    GBGames 3 days later:

    As I’ve said on Twitter (and tried to say in a comment that was eaten by spam filters apparently), thanks for the insight! I’ve learned a lot, and this post got me looking into using test-doubles in ways I haven’t seen before. I’ve been able to start working on my own project using the ideas presented here, although I quickly realized that I’ll need to find a nice C++ mock framework. Manual mocks are tedious and limited compared to the power Mockito has in your example.

    * Writing the actual hardware layer class will require TDDing it, and passing in an ILibSDL class. This is not strictly necessary, but if you want to test the HardwareLayer without using the real lib SDL, that’s your best option. *

    Let’s pretend libSDL was a live database in the hopes that it makes it easier to picture for non-game developers. In unit tests, we don’t want to use the live data, so we create a test-double to pretend to be the database. So far, so good. But at some point, something has to interface with the actual database, so is that glue code left untested in most projects?

    In this case, I know in C++ I can have multiple implementation files. If some parts of HardwareLayer can be unit tested, but other parts use libSDL, would it be expected that an implementation file can be set in a special part of the build directory structure so that the real project uses it but the test project does not even know of it?

    I feel like I’m otherwise going to keep pushing libSDL into abstractions forever, but that’s probably my inexperience with TDD and unit testing talking.

  6. Avatar
    Brett L. Schuchert 3 days later:

    GBGames wrote:

    But at some point, something has to interface with the actual database, so is that glue code left untested in most projects?

    (FWIW, see below for some comments on mocking in C++.)

    Well that is an option, but no I would not do that. In the case of the database, the vast majority of things getting tested do not depend on the database and therefore you can and should mock it out. An alternative is to use an in-memory database.

    However, in the case of the database, you’ll have a DAO (maybe) that needs to hit the database because that’s its responsibility. So you’ll have some tests that actually test that the DAO correctly uses the real database.

    But here are a couple of things to keep in mind:
    • I should be able to run these frequently (daily at the very least, on demand for an impatient person even better).
    • I should be able to run them at the same time as other people.
    • I should be able to run them on my developer machine as well as, for example, a build box (or a neutral machine)
    In the case of databases, this suggest we do NOT use live data, we own the database or somehow manage to make many instances of the same test not conflict when run in parallel. This suggests database isolation, which you can achieve in many ways:
    • Each test execution has its own database
    • In-memory database
    • Each test execution uses its own user in the database and then performs a cascade delete after each test of that user
    • ...

    By analogy, you’ll have some actual tests (notice how I’ve not used the word unit yet) that really test the use of libSDL. Are these unit tests? Are these integration tests?

    Frankly, I don’t care what you call them. The question I ask is are they useful? If so, then great.

    You’re still going to have challenges because the underlying libSDL may require verification manually. You might end up with manual tests instead of automated tests. Or you might have a mix of automated and manual tests.

    I take it libSDL is a COTS. So you are not strictly testing it (I assume), rather you are testing your use of it. That’s a very different thing indeed. (If you are verifying just interaction, that you can do with a test-double.)

    So how much of your use of it can be tested so that the window of manual or auto-assisted testing is small?

    This is a case where you might, for example, render actual results and then run a test and compare (electronically) generated to expected results. This is not great, but it is an option. You could create some basic tests – sort of like smoke tests. You make sure these pass before you, for example, hand them off to QA (if it is a separate organization).

    What is libSDL? Or better yet, can you give a code snippet that uses it? Something that might be in your HardwareLayer class (the real one, not a test-double). Are you writing libSDL or is it a library? And when you provide that snippet, could you tell me what it is you would like to verify.

    C++ Mocking Notes

    Ok, I have not used a tool for C++. There are some and I’d be interested in comments/recommendations. But here are a few things I’d keep in mind:

    • Feel free to inline virtual methods! Normally you should not do this, but it’s for a test so it’ll just make the .o for the test file bigger. It will not impact the real system.
    • Create test doubles in the same file as the test file. Test-doubles should be small and focused so you won’t need to share them across tests. If you do want to do that, it’s OK but don’t start there. It’s reasonable to have one or more unique test doubles PER TEST METHOD. When you use a mocking library you’re doing that anyway. You may not notice it.
    • If you have a complex interface (you should not, read up on the interface segregation principle), then create a test class that fully implements the interface with stubbed methods. The your test-doubles implement that. This way, if you change an interface, you really should only need to change that one test-double base class and keep things compiling.
    • You can simplify your tests by allowing many test classes per unit under test. Group by common setup. This comes from behavior driven development. I like this style. When I’m teaching TDD, I often move to this approach (I always mention it).
  7. Avatar
    Patrick Johnmeyer 8 days later:

    Both amop and googlemock are reasonable frameworks for C++ mocking.

  8. Avatar
    Marcel Popescu 28 days later:

    verify(layer, times(1)).setResolution(1024, 768); verify(layer, times(1)).setColorDepth(8);

    This is why I don’t like this type of test… the above simply duplicates the constructor; I fail to see how it helps in any but the most trivial way. Any time I want to change the implementation of the constructor, the test will have to change.

  9. Avatar
    FLV extractor 10 months later:

    fed uo with is

  10. Avatar
    write my speech about 1 year later:

    Thank you for the schema presenting in the article, useful for my colege papers!

  11. Avatar
    Designer Bags about 1 year later:

    cool article!Thanks for nice sharing

  12. Avatar
    Dog bark collar about 1 year later:

    verify(layer, times(1)).setResolution(1024, 768); verify(layer, times(1)).setColorDepth(8);

    This is why I do not like this kind of test. The above simply duplicates the constructor.

  13. Avatar
    Pandora about 1 year later:

    your initial website design may need to be frames based because you don’t have time to build an Ajax framework.

  14. Avatar
    http://www.whiteiphone4transformer.com about 1 year later:

    Look for the white iphone 4 avaiable online store? We may search on net for what you need.

  15. Avatar
    Solid State Relay about 1 year later:

    This article is very usefull for me! I can see that you are putting a lots of efforts into your blog. I will keep watching in your blog, thanks.

  16. Avatar
    Mulberry Outlet about 1 year later:

    I bookmarked your blog but I hope you will post more…

  17. Avatar
    okey oyunu oyna about 1 year later:

    Very very nice.

    internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.

  18. Avatar
    cookies gift baskets over 2 years later:

    hmm ,i’m not sure if this is what i’m looking for but anyway this is interresting and could be useful some day,thanks for taking time to write such cool stuff

  19. Avatar
    beats by dr dre studio over 2 years later:

    Designed with unique features that you won’t find on ordinary beats by dr dre pro detox with the Beats by Dr. Dre Studio headphones you not only get incredible sound, but advanced, useful function to make your listening experience the best it can be. With advanced speaker design, powered amplification, and active noise canceling, the headphones delivers all the power, clarity and deep bass today’s top artists and producers want you to hear.

  20. Avatar
    beats by dr dre over 2 years later:

    beats by dr

    dre beats by dre

    sale cheap beats by

    dre beats by dre

    store high quality

    headphones new design

    headphones

    drdre-studio-limited-edition-colorful-champagne-p-180.html”>cheap beats

    by dr.dre studio limited edition-colorful champagne

    drdre-studio-limited-edition-colorful-champagne-p-180.html”>cheap beats

    by dr.dre colorful champagne

    drdre-studio-limited-edition-colorful-champagne-p-180.html”>colorful

    champagne headphones

    Cheap Beats By

    Dre Dr Dre

    Headphones Cheap Monster

    Beats Headphones Beats By Dr

    Dre

    -drdre-c-69.html”>New Style Beats By Dre Headphones

    studio-c-89.html”>Cheap Dr Dre Studio Headphones

    studio-c-89.html”>Beats By Dre Studio

    -c-90.html”>Cheap Dr Dre Pro Headphones

    -c-90.html”>Beats By Dre Pro

    solo-c-91.html”>Cheap Dr Dre Solo Headphones

    solo-c-91.html”>Beats By Dre Solo

  21. Avatar
    ssf@fd.com over 2 years later:

    Molded Case Circuit Breaker rated insulation voltage of this circuit breaker is 750V which is applicable for the electricity distribution net of AC 50Hz It is used to Mini Circuit Breaker power and protect the line and power apparatus from being overload and short-circuit protection of the mini rcbo. This Residual Current Circuit Breakercan be installed vertically and horizontally.rcbo

  22. Avatar
    bagsupplyer over 2 years later:

    wholesale women replicate Coach backpacks more order,more discount

  23. Avatar
    casque dr dre over 2 years later:

    casque dr dre cher casque beats by dre beats casque distributors casque beats by dre online beats by dr dre casque

    nouveau style dr dre beats cher nouveau arriver dr dre beats beats by dr dre spiderman casque casque spiderman beats by dre

    beats by dr dre superman casque superman beats by dre casque

    casque chrome colorware casque beats by dre chrome colorware

    Cheap Beats By Dre Dr Dre Headphones Cheap Monster Beats Headphones Beats By Dr Dre

    New Style Beats By Dre Headphones

    Cheap Dr Dre Studio Headphones Beats By Dre Studio

    Cheap Dr Dre Pro Headphones Beats By Dre Pro

    Cheap Dr Dre Solo Headphones Beats By Dre Solo

    beats by dr dre beats by dre sale cheap beats by dre beats by dre store high quality headphones new design headphones

    cheap beats by dr.dre studio limited edition-colorful champagne cheap beats by dr.dre colorful champagne

  24. Avatar
    Tips For Bowling over 2 years later:

    There is only one thing which can master the perplexed stuff of epic material into unity; and that is, an ability to see in particular human experience some significant symbolism of man’s general destiny.

  25. Avatar
    Moncler store over 2 years later:

    doudoune moncler Pas Cher Thomas is characterized by a pattern of red and white strips on chest with a logo patch. drawstring hood,two side vertical zip pockets at waist and button down with hidden zip closure.There is also a logo patch on sleeve. As a fashion leader, Eric has a pattern of white and green strips with Moncler logo patch on the left sleeve. Full white zip closure is in front while two zip pockets at Moncler online store.

  26. Avatar
    beats by dr dre over 2 years later:

    A university studentbeats by dr dre caught by the enemy, the enemy tied him at the poles,just beats solo headphones purple and then asked him: say, where are you? You do not say it electrocuted! Scheap dr.dre beats studio headphones balck/yellowtudents back to the enemy a word, the result was electrocuted, he said: I am TVU.Hot sale beats by dr dre pro headphones

  27. Avatar
    bladeless fans over 3 years later:

    TDDing an Interface – a Twitter influenced discussion 26 good post62

  28. Avatar
    louboutin sales over 3 years later:

    TDDing an Interface – a Twitter influenced discussion 27 hoo,good article!!I like the post!143

  29. Avatar
    janine Edwards over 3 years later:

    There is also a logo patch on sleeve. As a fashion leader, Eric has a pattern of white and green strips with Moncler logo patch on the left sleeve. Full white zip closure is in front while two zip pockets at Moncler online store.

  30. Avatar
    solar panels in derby over 3 years later:

    your listening experience the best it can be. With advanced speaker design, powered amplification, and active noise canceling, the headphones delivers all the power, clarity and deep bass today’s top artists and producers want you to hear.

  31. Avatar
    cosplay outfits costumes over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/inuyasha-cosplay Deluxe InuYasha Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  32. Avatar
    costumes cosplay over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/japanese-school-uniform-cosplay Deluxe Japanese School Uniform Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  33. Avatar
    cosplay outfit over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/the-prince-of-tennis-cosplay Deluxe The Prince Of Tennis Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  34. Avatar
    cosplay outfits over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/yu-yu-hakusho-cosplay Deluxe Yu Yu Hakusho Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  35. Avatar
    cosplay girl over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/movie-tv-cosplay Deluxe Movie & TV Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  36. Avatar
    girl cosplay over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/miscellaneous-cosplay Deluxe Miscellaneous Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  37. Avatar
    shop cosplay over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/vampire-knight-cosplay Deluxe Vampire Knight Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  38. Avatar
    cosplay 2012 over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/neon-genesis-evangelion-cosplay Deluxe Neon Genesis Evangelion Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  39. Avatar
    buy cosplay over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/kingdom-hearts-cosplay Deluxe Kingdom Hearts Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  40. Avatar
    cosplay buy over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/ouran-high-school-host-club-cosplay Deluxe Ouran High School Host Club Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  41. Avatar
    cosplay deviants over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/negima-magister-negi-magi-cosplay Deluxe Negima! Magister Negi Magi Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  42. Avatar
    cosplay dress over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/kids-costumes Deluxe Kids’ Costumes Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  43. Avatar
    cosplay store over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/vocaloid-cosplay Deluxe Vocaloid Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  44. Avatar
    japanese cosplay over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/s-a-special-a-cosplay Deluxe S · A: Special A Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  45. Avatar
    wigs cosplay over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/kashimashi-girl-meets-girl-cosplay Deluxe Kashimashi: Girl Meets Girl Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  46. Avatar
    cosplay wigs over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/katekyo-hitman-reborn-cosplay Deluxe Katekyo Hitman Reborn! Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  47. Avatar
    cosplay shops over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/lucky-star-cosplay Deluxe Lucky Star Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  48. Avatar
    cosplay stores over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/macross-frontier-cosplay Deluxe Macross Frontier Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

  49. Avatar
    best cosplay over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/metal-gear-solid-cosplay Deluxe Metal Gear Solid Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

Comments