*Updated* 2 Mai 2011: The "dynamic" keyword in C#4 was not meant to be used in the below scenario. Use VS2010 code completion instead.
We know that if you are using TDD, then you should write your test before you are implementing anything else, don’t we :-)
Figure: 1. Write a failing test (red), 2. Make the test pass (green), 3. Refactor your code
But if you are thinking about new methods, you can’t really run the tests because your unit test wont compile, see the following example.
[TestMethod()] public void CalculatorThingAdd_2PositiveNumbers_ResultAdded() { // Arrange CalculatorThing myCalculator = new CalculatorThing(); int result = 0; int expcected = 3; // Act result = myCalculator.Addition(1, 2); // Assert Assert.AreEqual(result, expcected); }
BAD code example: In TDD I would like to run this test, before I implement the method “Addition”
On compiling this test, you get the following error message
Error 1 'ConsoleApplication.CalculatorThing' does not contain a definition for 'Addition' and no extension method 'Addition' accepting a first argument of type 'ConsoleApplication.CalculatorThing' could be found (are you missing a using directive or an assembly reference?)
Figure: Code want compile, because “Addition” is not implemented, and C# is static type safe on compile time
But you can avoid this by using the dynamic keyword, see below
[TestMethod()] public void CalculatorThingAdd_2PositiveNumbers_ResultAdded() { // Arrange dynamic myCalculator = new CalculatorThing(); int result = 0; int expcected = 3; // Act result = myCalculator.Addition(1, 2); // Assert Assert.AreEqual(result, expcected); }
GOOD code example: This code compiles nicely
Figure: Code compiles, because myCalculator is a dynamic object and evaluated on runtime not on compile time
But if you run this test you get:
Figure: Test failed because method not implement
Test method CalculatorConsole.Tests.CalculatorTest.CalculatorThingAdd_2PositiveNumbers_ResultAdded threw exception:
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'ConsoleApplication.CalculatorThing' does not contain a definition for 'Addition'
NICE!!!!
We have a failing test!
Now go and implement the method and make the test pass!
5 comments:
Hi Peter,
this is a very interesting approach. I hate to have to go to the class and to create methods with "return null;"
or
"throw new NotImplementedException();"
I'm looking forward to C# 4.0 and Visual Studio 2010 :-)
Nice, takes a little of the pain out of testing.
I don't see any benefit from this. You have to implement the method anyway and afterwards you even would have to modify the test in order to get rid of this fake behavior.
You first write the test and let the code completion feature create the method. Run the test to see whether everything is connected as it should be (could become green if not). Then fill the method with life and run the test again. That's what TDD is all about.
In case you develop a multi-component architecture, use a mocking framework to simulate behaviors of components which do not exist yet.
This not like TDD is ment. According to the examples of Kent Beck (the TDD "inventor"), create a real method und let it fail.
@Robgert and @Rainer
Agree!
I had the idea that this could be a good usage of dynamic types.
Because the types that we are testing, don't have the needed behavior yet...
As Rainer said, I don't like the approach either, to go back and change "dynamic" to the implementation type.
Post a Comment