Hi Guys,

I'm a new TDD'er and I'm already witnessing significant increases in
bug findings in my own code. I can't understand how I built software
in the past without MbUnit and Rhino Mocks. I support webforms was a
big set back, but now that MS MVC is in the works, i'm building more
reliable sites already.

The idea of creating mock harnesses, environments and relationships is
kinda addictive for exploring the limits of function. But, when I
can't think of a good way to test my DAL. Now 3.5 is out, I've jumped
onto LINQ-to-SQL ORM cos it's so well implemented, but unit testing it
isn't very easy. For those that have jumped onto MS ORM, is there a
general pattern I can follow to unit test my DAL?

Since I can't mock or fake my DAL, I'm writing to the database in each
test and relying on RollbackAttribute to erase the changes. This works
great for simple single threaded tests, but I'm having issues
accessing database changes in a thread separate to the [Test] method.

I'm trying to test a simple scheduling system. The code for the class
is:

public class ReminderManager {
        public const string ReminderManagerKey = "ReminderManager";

        private ScheduleTimer timer = new ScheduleTimer();
        public ScheduleTimer Timer { get { return timer; } }

        private DateTime lastCheckTime = DateTime.Now;
        public DateTime LastCheckTime { get { return
lastCheckTime; } }

        public event Schedule.ExceptionEventHandler CheckError
        {
            add
            {
                timer.Error += value;
            }

            remove
            {
                timer.Error -= value;
            }
        }

        public void SetUpTimer(IScheduledItem schedule) {
            timer.AddJob(schedule, new Action(CheckForReminders));
            timer.Start();
        }
        public void TearDownTimer() {
            timer.Stop();
        }

        protected virtual void CheckForReminders() {

            DateTime now = DateTime.Now;


            // check for reminders between now and last event
            CharlesNicholasDataContext db = new
CharlesNicholasDataContext();
            var reminders = from r in db.Reminders where
r.DateTime>lastCheckTime && r.DateTime<=now
                            select r;

            int numrems = db.Reminders.Count();
            foreach (var reminder in reminders) {
                Launch(reminder);
            }

            // update last checked
            lastCheckTime = now;
        }

        protected virtual void Launch(Reminder reminder)
        {
            string message = "{3} Should send SMS to {0} on number
{1}";
            Console.WriteLine(message, reminder.Client.FirstName,
reminder.Client.MobileNumber,reminder.DateTime.ToShortTimeString());
        }

    }

My First test checks that CheckReminders is called periodically. I use
the Test specific subclass pattern to override CheckReminder for the
following test:
        [Test]
        [Duration(4000d)]
        public void EnsurePeriodicReminderChecking()
        {
            var rmtest = new ReminderManagerTest();
            rmtest.SetUpTimer(HalfSecondSchedule());
            System.Threading.Thread.Sleep(750);
            Assert.IsTrue(rmtest.NumberOfChecks == 2); // 2 includes
start of timing AND first tick
            rmtest.TearDownTimer();
        }

The second test is causing me grief - it needs to test that reminders
of the specific criteria are actually discovered and launched.
        [Test]
        [RollBack]
        [Duration(4000d)]
        public void LaunchSms() {
            // add fake but valid db data
            var client = FakeClient();
            db.Clients.InsertOnSubmit(client);
            db.SubmitChanges();

            var message = FakeMessage();
            db.ReminderMessages.InsertOnSubmit(message);
            db.SubmitChanges();

            var rem = FakeReminder();
            rem.ReminderMessageId = message.Id;
            rem.ClientId = client.Id;
            db.Reminders.InsertOnSubmit(rem);
            db.SubmitChanges();

            // run once off timer
            manager.SetUpTimer(OnceOff());
            int numres = db.Reminders.Count();
            System.Threading.Thread.Sleep(20000);

            // TODO check sms message is launched
            // TODO check send sms return code is given

        }

So, in the test thread, I create a fake reminder, message and client
and submit to the database. Then in the ReminderManager
CheckReminders() it needs to read those fake records and should find
the fake records.

In the [Test] method, the numRes integer is 2, but in the
CheckReminders() method, numRes is 1. It's like the db changes in the
first thread aren't visible from the second, even though no exception
is thrown.

Is there an obvious explanation for that? Will the removal of Rollback
make the database changes visible from the ReminderManager
ScheduleTimer thread?

This is a bit mind boggling.

Thanks for your help,
-Vijay
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"MbUnit.User" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/MbUnitUser?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to