TDDing an Interface - a Twitter influenced discussion 49
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.
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.
- Create interfaces
- Add methods to those interfaces needed to add functionality
- Set expectations on the use of those interfaces
- 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);
}
}
- 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
I know this sounds picky, but these are the sort of questions that we’ve found forces our code into making sense.
I know this sounds picky, but these are the sort of questions that we’ve found forces our code into making sense.
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.
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
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.
GBGames wrote:
(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: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 NotesOk, 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:
Both amop and googlemock are reasonable frameworks for C++ mocking.
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.
fed uo with is
Thank you for the schema presenting in the article, useful for my colege papers!
cool article!Thanks for nice sharing
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.
your initial website design may need to be frames based because you don’t have time to build an Ajax framework.
Look for the white iphone 4 avaiable online store? We may search on net for what you need.
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.
I bookmarked your blog but I hope you will post more…
Very very nice.
internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.
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
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.
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 ByDre 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
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
wholesale women replicate Coach backpacks more order,more discount
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
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.
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.
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
TDDing an Interface – a Twitter influenced discussion 26 good post62
TDDing an Interface – a Twitter influenced discussion 27 hoo,good article!!I like the post!143
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.