views:

119

answers:

3

I just read this post and it makes the case against implicit typing using when starting out with Test driven development/design.

His post says that TDD can be "slowed down" when using implicit typing for the return type when unit testing a method. Also, he seems to want the return type specified by the test in order to drive development (which makes sense to me).

A given unit test with implicit typing might look like this:

public void Test_SomeMethod()
{
    MyClass myClass = new MyClass();

    var result = myClass.MethodUnderTest();
    Assert.AreEqual(someCondition, result);
}

So my questions are:

Does using implicit typing help or hinder writing unit tests for TDD? Is there anyone out there that can share their experience using this technique when writing unit tests?

I ask this because soon I have not done TDD and want to know if there is a way to write generic or semi-generic unit tests that would work a return type might change.

+3  A: 

I see his point but I don't really think it's the right reason to not use var here. Remember, TDD works roughly according to the following:

  1. Write a new test.
  2. If test fails to compile (and it should fail!), write enough code until the test compiles.
  3. Run all tests.
  4. If a test fails, write enough code until all tests pass.
  5. Refactor.

Whether or not we use var the test will fail to compile either way because the method under test won't exist yet!. Once we start coding up NewMethod his points are rather moot.

Rather, the right reason to not use var here is because the code gives no indication what the type of result is. This is a matter of opinion but var is okay here

var dict = new Dictionary<Foo, List<Bar>>();

and for anonymous types but not here

var m = M();

because it's completely unclear without going to the declaration of M (or using IntelliSense) what the return type of M is.

Jason
`SomeType m = M();` isn't necessarily any clearer. `m` is a terrible variable name. If you change it to a *good* variable name, then will you still need to see the type?
Kyralessa
the actual type should bot be important. It's an implementation detail and should at best _not_ be known at the line var m = M(); the type has nothing to do with readability of the code. However the name of the variable will be repeated everytime it's used and should be chosen carefully
Rune FS
I had the same thought about the test, as well. A unit test that doesn't compile is still a test. But as far as the implicit typing is concerned, will it help out when testing returned results (that have descriptive variable names, of course)? Or should returned results be explicitly typed?
cmw
@Rune FS: The return type is important and is absolutely not an implementation detail that should be hidden! It's part of the public behavior of the method under test.
Jason
@Kyralessa: Yes. I consider `var methodResult = M();` to be marginally more readable than `var m = M();` but not readable enough.
Jason
@cmw: Yes it is my opinion that returned results be explicitly typed with the exception of methods that are returning anonymous types (e.g., `var projection = items.Select(x => new { x.SomeKey, x.SomeValue });`).
Jason
`methodResult` is a terrible name too. How about `var customersInSelectedState = M();`? Now do you still need to know the type of `customersInSelectedState`, or will Intellisense make it clear enough?
Kyralessa
@Jason it sure is part of the methods signature but the statement var m = M(); is _not_ part of any API it's part of the implementation of a test and I see no reason why the test should change when someone realizes that using List<T> in a public signature is an error it should be returned IList<T> or other suitable interface
Rune FS
@Rune FS: That just says `m` should have been declared as `IList<T>` in the first place.
Jason
@Jason certainly not you're missing the point. Not using var Will Force your code to change even when it didn't have to. That is always a bad thing. Secondly for what exactly do you need the type when it comes to readability?var name = getName();for(var i = 0;name.Length;i++) Console.write(name[i])I don't need to know the type of either i or name to read that code or describe _what_ it does. I would know _how_ (is name a string, an array or ... ) but that's not readability but debuging
Rune FS
@Rune FS: I am not missing the point. Using `var` like that is a hindrance to readability. I maintain that `IList<string> names = getNames(); for(int i = 0; i < names.Count; i++) Console.WriteLine(names[i]);` is far more readable than what you presented. Quick, what is the type of `a`, `b`, `c`, `d`, `e` and `f` in `var a = 2147483647; var b = 2147483648; var c = 4294967295; var d = 4294967296; var e = 9223372036854775807; var f = 9223372036854775808;`? (Thanks, Jon Skeet!)
Jason
Since you're asking me what the comcrete type is you are missing the point :) cuz my point is that you shouldn't care (when it comes to readability) staying otherwise would be stating that languages such as F#, OCaml, Python arrn't readable and that any dynamically typed language can't be used if you wish to produce readable code. Ny not using var you're introducing a potetial (compile time) bug. Do you value that a good thing?
Rune FS
@Rune FS: Using `var` like that makes the code more obscure. It does not enhance readability.
Jason
@Jason, that's a cute trick, but again, you're using crappy variable names. Putting int, uint, long, etc. in front of those won't cause them to suddenly become intelligible. The *type* of a variable is not documentation; the *name* of a variable is documentation.
Kyralessa
+1  A: 

Yes and No

In Visual Studio presently, TDD is a bit of a pain, especially when using implicity typing. var means no intellisense, then when you enter the name of a type that may not exist yet it has the tendency to auto-complete with something that is similiar to what you are typing, often the name of the test fixture.

Visual Studio 2010 has a consume first mode, which makes it ideal and better for Test Driven Development. Currently you'll find (in 2008 and earlier) you have to hit escape to hide intellisense.

As for use of var it's purely synatic sugar. It makes the following much nicer in my opinion:

var type = new MyType();

Its clear that the variable type, is of type MyType. var is great for generics and follows the prinicple of DRY - Don't Repeat Yourself.

var type = MethodCall();

var result = ReturnResult();

On the other hand, this makes for hard to read code, whether you follow TDD or not. Good unit tests should flow and be easy to read. If you have to think, or hover the mouse over a method to see the return type, that is the sign of a bad, hard to read test.

Finglas
why do you think var type = MethodCall(); is hard to read?what type 'type' is should usually (in my opinion) not be important to reading the code (the name of the variable on the other hand should be choosen to increase readability)
Rune FS
I've added another example. Result could be anything, a string, int, another object and so on. Even with a sensible name, confusion can occur. *var* is awesome, but it's best not to abuse it.
Finglas
A: 

From a tooling perspective, I'd say it's nicer to avoid the var. I use Eclipse and Java, but I know that extensions like CodeRush and Resharper offer many of the features that I'm discussing here. When in my test I call a method that doesn't exist yet, I can "quick fix" it to create the method in the desired class. The return type of the automatically created method depends on its context; if I am expecting back a String, the return type of the method will be String. But if the assignment is to a var (which Java doesn't have - but if it did), the IDE wouldn't know enough to make the return type anything other than var (or maybe Object).

Not everyone uses the IDE in this way in TDD, but I find it very helpful. The more information I can give the IDE in my test, the less typing I have to do to make the test pass.

Carl Manaster
Sometimes I wish VS2008 had some of the features that Eclipse does. :-)
cmw
@cmw - look into CodeRush they have some features that even Eclipse users can envy.
Carl Manaster