views:

384

answers:

2

I'm making my first steps in Test Driven Development with Visual Studio. I have some questions regarding how to implement generic classes with VS 2010.

First, let's say I want to implement my own version of an ArrayList. I start by creating the following test (I'm using in this case MSTest):

[TestMethod]
public void Add_10_Items_Remove_10_Items_Check_Size_Is_Zero() {
    var myArrayList = new MyArrayList<int>();

    for (int i = 0; i < 10; ++i) {
        myArrayList.Add(i);
    }

    for (int i = 0; i < 10; ++i) {
        myArrayList.RemoveAt(0); //should this mean RemoveAt(int) or RemoveAt(T)?
                                 //VS doesn't know. Any work arounds?
    }

    int expected = 0;
    int actual = myArrayList.Size;
    Assert.AreEqual(expected, actual);
}

I'm using VS 2010 ability to hit

ctrl + .

and have it implement classes/methods on the go.

  1. I have been getting some trouble when implementing generic classes. For example, when I define an .Add(10) method, VS doesn't know if I intend a generic method(as the class is generic) or an Add(int number) method. Is there any way to differentiate this?
  2. The same can happen with return types. Let's assume I'm implementing a MyStack stack and I want to test if after I push and element and pop it, the stack is still empty. We all know pop should return something, but usually, the code of this test shouldn't care for it. Visual Studio would then think that pop is a void method, which in fact is not what one would want. How to deal with this? For each method, should I start by making tests that are "very specific" such as is obvious the method should return something so I don't get this kind of ambiguity? Even if not using the result, should I have something like int popValue = myStack.Pop() ?
  3. How should I do tests to generic classes? Only test with one generic kind of type? I have been using ints, as they are easy to use, but should I also test with different kinds of objects? How do you usually approach this?
  4. I see there is a popular tool called TestDriven for .NET. With VS 2010 release, is it still useful, or a lot of its features are now part of VS 2010, rendering it kinda useless?
  5. Whenever I define a new property in my test code, and ask VS to generate that method stub for me, it generates both a getter and a setter. If I have something like int val = MyClass.MyProperty i'd like to to understand that (at least yet) I only want to define a getter.

Thanks

+3  A: 

I see there is a popular tool called TestDriven for .NET. With VS 2010 release, is it still useful, or a lot of its features are now part of VS 2010, rendering it kinda useless?

It's still useful in case you use one of a number of different unit testing frameworks (nunit, mbunit, xunit, csunit, etc).

There are also other tools (like Visual Nunit) that provide visual studio integration for running unit tests.

R0MANARMY
From what I've seen on Channel9, you can also use several frameworks with VS 2010. But I've not tried to test it.
devoured elysium
@devoured elysium: I've gotten the Visual Studio test runner to run NUnit tests. The problem with MSTest you may (or may not) run into is if you want to a Continuous Integration server (like TeamCity or CruiseControl.NET) you won't be able to run MSTest unit tests without installing visual studio on the server (which is kind of an annoying requirement).
R0MANARMY
+3  A: 

To your code sample, why would you have a method RemoveAt(T obj)?

You can do RemoveAt(int index) and Remove(T obj) instead. Take a look at Microsoft's APIs (for example, for List<T>) that see how they set up the Remove methods for a generic collection.

And now for your points:

1: What would Add(int number) do? If I understand your intentions correctly, Add(10) can only be intepreted as "Add value 10 at the end of my collection". If you wanted to add a value at a particular index, you can (and probably should) name that method Insert: Insert(int index, T value).

2: sure, Visual Studio will interpret the method as void at first, but you can edit it to be something like

public class MyStack<T>
{
    public T Pop() 
    {
    }
}

The stubs built by pressing Ctrl+. are a convenience, but not gospel. You don't HAVE to always assign a return value to a variable. If you don't need it in a test, don't do it. If you want VS to pick up on a return type other than void, you can write a different unit test (e.g. that Pop() returns the last pushed value).

3: I'd test with the types that I see most frequently used in my code. If you're writing a public API, then test with as many types as possible. If you're using NUnit, look into using the [TestCase] attribute to help you avoid writing some duplicate code.

4: I still use TestDriven, but I haven't tried going without it, so I can't really make a useful comparison.

5: Just delete the setter if you don't need it. Some addon frameworks like ReSharper support more advanced code generation, including read-only properties.

Anna Lear
Reread the questions. You are completly off the point.I want a RemoveAt(int), but as I'm using a MyArrayList<int>(), Visual studio doesn't know which method I want to implement..
devoured elysium
@devoured elysium: How is your MyArrayList<T> class defined? There should never be any confusion between which method to implement in this case because there is only one RemoveAt() and it accepts an index into the array. If you wanted to remove an integer value from your list, you would use Remove() instead.
Anna Lear
My questions here are mostly concerned with VS 2010 stub generation features, not on how to develop classes. Anyway, I want a Add(T element) and RemoveAt(int index).
devoured elysium
Well, sure I can then change the return type of methods stubs, as I can also implement all by hand without using VS 2010 stub generation feature. I'd just like to know if there are ways of avoiding having the extra work.
devoured elysium
@devoured elysium: Ahhhhh, I see what you mean. I don't think Visual Studio right now is able to pick up on the fact that your class is generic when you generate stub methods. Adjusting those types would unfortunately have to be a manual step, regardless of whether you use int or string or any other type for your T.
Anna Lear