views:

88

answers:

4

Hello, I am relatively new to using TDD and have been reading about mocking objects lately. I have the following test to test a method that given a date returns the next saturday.

[TestMethod()]
        public void NextSaturdayTest()
        {
            DateTime date = new DateTime(); 
            date = DateTime.Parse("2010-08-14");
            DateTime expected = new DateTime(); 
            expected = DateTime.Parse("2010-08-21");
            DateTime actual;
            actual = DateExtensions.NextSaturday(date);
            Assert.AreEqual(expected, actual);

            date = DateTime.Parse("2010-08-19");
            expected = DateTime.Parse("2010-08-21");
            actual = DateExtensions.NextSaturday(date);
            Assert.AreEqual(expected, actual);
        }

first off, does this represent good testing practices? Second, what is the advantage of utilizing a mock framework to create this test?

Let me know if I can offer any more information.

Thanks for any thoughts

+5  A: 

Mocking is used to satisfy dependencies.

For instance. Consider if you have a class that loads users from a database using a IDataLayer (wrapper around the database)

public class UserService
{
    public UserService(IDataLayer layer) {}
    public User GetById(int id)
} 

When testing, you don't want to test against a database. It makes it hard to provide data and check the result. Instead, you mock a IDataLayer object to be able to manually provide a user to the UserService. It makes it a whole lot easier to validate that the UserService does what it's supposed to do.

As for your test method. I would break it up into two methods, since you are running two different tests (on the same method though)

jgauffin
+2  A: 

In this case a mocking framework is not necessary and thus shouldn't be used.

Your test is fairly reasonable. I would personally inline most of the date parsing for better readability:

[TestMethod()]
    public void NextSaturdayTest()
    {
        DateTime actual = DateExtensions.NextSaturday(DateTime.Parse("2010-08-14"));
        Assert.AreEqual(DateTime.Parse("2010-08-21"), actual);

        actual = DateExtensions.NextSaturday(DateTime.Parse("2010-08-19"));
        Assert.AreEqual(DateTime.Parse("2010-08-21"), actual);
    }
Grzenio
+6  A: 

First, don't do this:

DateTime date = new DateTime();
date = DateTime.Parse("2010-08-14");

You are creating a new datetime, then throwing it away when you parse a string to get a new datetime.Remember, test code should still be good code.

Second, a good test tests one thing. You may have multiple tests like ReturnsCorrectNextSaturdayGivenAWednesday, ReturnsCorrectNextSaturdayWhenCrossesEndOfMonth, and ReturnsCorrectNextSaturdayWhenCrossesEndOfYear.

And finally, there's no reason to mock here. A mock would be appropriate if your DateExtensions called into another component (say a database), and you wanted to fake that call. So instead of testing DateExtensions + Data Access, you'd only be testing the DateExtensions and when it called the data access layer, it would be a mock that your test set up.

Philip Rieck
+2  A: 

I think you're okay without mocking in this case. Typically you'd mock some sort of dependency (for example, if you had a DateProvider or something), but in this case, using DateTime directly looks good to me.

I would, however, clean up your test some. You should stick to testing one thing per method, because if that test method fails, you will know WHY it failed instead of having to examine the asserts and wonder if the rest of them would've passed.

[TestMethod()]
public void NextSaturdayReturnsCorrectValueStartingFromASaturday()
{
    DateTime date = DateTime.Parse("2010-08-14");

    DateTime expected = DateTime.Parse("2010-08-21");
    DateTime actual = DateExtensions.NextSaturday(date);

    Assert.AreEqual(expected, actual);
}

[TestMethod()]
public void NextSaturdayReturnsCorrectValueWithinTheSameWeek() 
{
    DateTime date = DateTime.Parse("2010-08-19");
    DateTime expected = DateTime.Parse("2010-08-21");
    DateTime actual = DateExtensions.NextSaturday(date);

    Assert.AreEqual(expected, actual);
}

And as others suggested, continue expanding your test class to include checks for some of the stranger situations you might encounter.

Anna Lear