I think you have the right idea, but I think you are making this into a bigger deal than it is. If you start doing TDD, your first reaction will probably be 'is this it?'. And then later, you should hopefully say 'aha'!
The main thing is that you get nUnit, learn the tutorial, and then make sure you write a test for everything you do before you write the implementation. You might skip over writing tests for property accessors, but anything that requires any calculations, you should write a test first.
So, pretend you're testing a calculator's Add(int 1, int 2), the first thing you think is, 'how can I break this'. My ideas where things could go wrong are: negative numbers, zeros, and overflows. The trick is to imagine every mistake the person who is going to create the Add() method might make, and then write a test against it. So, I might write:
Assert.AreEqual(5, calc.Add(2, 3), "Adding positives not as expected");
Assert.AreEqual(-5, calc.Add(-2, -3), "Adding negatives not as expected");
Assert.AreEqual(-2, calc.Add(-3, 2), "Adding one positive and one negative not as expected");
// your framework might provide a cleaner way of doing this:
try {
int result = calc.Add(Int32.Max, 5);
Assert.Fail("Expected overflow error. Received: " + result);
} catch(Exception e) {
// This should be a more specific error that I'm not looking up
}
So, as you can see, what I've tried to do is figure out how the Add() method might not work, and then test against it. I've also looked for interesting corner cases and explicitly defined the behaviour that I'm expecting. And then now I'm free to go off and code the Add() method.
Now, while that's not all that great, you know that your Add() method will be rock-solid for when you start creating complex math functions that combine your Sin() method with your Sqrt() method along with your Add() method.
That, for better or worse, is Test Driven Development. Don't get too hung up on the interfaces or dependency injection for now. That can come later, if you need it.