Posts Tagged ‘Castle’

Using Factories for testing Castle ActiveRecord: Part 2 : Rearden

Thursday, January 8th, 2009

Earlier I posted about using factories for testing Castle ActiveRecord. I now have an update that I call Rearden.  Here is is:

using System;
using System.Collections.Generic;
using Castle.ActiveRecord;
 
namespace Rearden
{
    public delegate void ModifyClass(ActiveRecordClass instance, IDictionary overrides);
 
    ///
    /// This is a factory to create test objects for Castle ActiveRecord.
    ///
    public static class Factory
    {
        // overload to call without overrides
        public static ActiveRecordClass Init(ModifyClass modifyClass)
        {
            return Init(modifyClass, new Dictionary());
        }
 
        // instanciate and set values in ActiveRecordClass
        public static ActiveRecordClass Init(ModifyClass modifyClass, IDictionary overrides)
        {
            ActiveRecordClass instance = (ActiveRecordClass)Activator.CreateInstance(typeof(ActiveRecordClass));
            modifyClass(instance, overrides);
            return instance;
        }
 
        // overload to call without overrides
        public static ActiveRecordClass Make(ModifyClass modifyClass)
        {
            return Make(modifyClass, new Dictionary());
        }
 
        // create, save and flush ActiveRecordClass
        public static ActiveRecordClass Make(ModifyClass modifyClass, IDictionary overrides)
        {
            ActiveRecordClass instance = Init(modifyClass, overrides);
            ActiveRecordBase asBase = instance as ActiveRecordBase;
            asBase.SaveAndFlush();
            return instance;
        }
 
    }
 
}

Add the compiled Rearden Assembly to your Test Assembly and then create a Blueprint class:

using System;
using System.Collections.Generic;
using System.Text;
 
namespace Quality.Model
{
    public static class Blueprints
    {
        public static void Blueprint(Employee emp, IDictionary overrides)
        {
            emp.FirstName = overrides.ContainsKey("FirstName") ? (string)overrides["FirstName"] : Faker.NameFaker.FirstName();
            emp.LastName = overrides.ContainsKey("LastName") ? (string)overrides["LastName"] : Faker.NameFaker.LastName();
            emp.Xid = overrides.ContainsKey("Xid") ? (string)overrides["Xid"] : Faker.StringFaker.Randomize("X######");
        }
 
        public static void Blueprint(Foo foo, IDictionary overrides)
        {
            foo.Month = overrides.ContainsKey("Month") ? (DateTime)overrides["Month"] : new DateTime(Faker.NumberFaker.Number(2000, 2009), Faker.NumberFaker.Number(1, 12), 1);
            foo.Employee = overrides.ContainsKey("Employee") ? (Employee)overrides["Employee"] :  (Employee)Rearden.Factory.Make(Blueprint);
        }
    }
}

And now your test looks like:

        [Test]
        public void Can_find_by_Xid()
        {
 
            _values["Xid"] = "X123456"; // Dictionary
            Rearden.Factory.Make(Blueprints.Blueprint, _values);
            Employee fromDB = Employee.FindByXid("X123456");
            Assert.AreEqual("X123456", fromDB.Xid);
        }

Using Factories for testing Castle ActiveRecord

Wednesday, January 7th, 2009

Yesterday, John Nunemaker declared January to be Test Awareness Month in his post Test or Die.  The post is aimed at the Rails community but why stop there?  I’ve been working with Castle ActiveRecord today and since I’ve liked the plugin Machinist for Rails I decided to use the idea of using a factory to create test data.   The basic idea is that the factory class will create your record in the database that you would like to test.  There is a nice post on how to use it with Faker on the Advent2008 blog

I found a version of Faker for .Net and wired up a test factory for an ActiveRecord Employee class as follows.   I’m sure there is plenty of room for future refactoring and abasraction, but here is the basic idea:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class EmployeeFactory
    {
        // user set values
        private IDictionary _values = new Dictionary();
        public IDictionary Values
        {
            get {return _values;}
            set { _values = value; }
        }
 
        // clears user set values
        public void ResetValues()
        {
            _values.Clear();
        }
 
        // creates an instance with data but does not save it
        public Employee Init()
        {
            Employee emp = new Employee();
 
            emp.FirstName = _values.ContainsKey("FirstName") ? _values["FirstName"] : Faker.NameFaker.FirstName();
            emp.LastName = _values.ContainsKey("LastName") ? _values["LastName"] : Faker.NameFaker.LastName();
            emp.Xid = _values.ContainsKey("Xid") ? emp.Xid = _values["Xid"] : Faker.StringFaker.Randomize("X######");
 
            return emp;
        }
 
        //creates, saves and flushes
        public void Make()
        {
            Init().SaveAndFlush();
        }
 
        // creates x number of Employee records.
        public void Make(int times)
        {
            for (int i = 0; i < times; i++)
            {
                Make();
            }
        }
    }

This allowed me to write tests such as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
   public class EmployeeTestCase : AbstractModelTestCase
    {
        private EmployeeFactory _factory;
 
        [SetUp]
        public void SetUp()
        {
            _factory = new EmployeeFactory();
            PrepareScope();
        }
 
        [Test]
        public void Can_find_by_Xid()
        {
            _factory.Values["Xid"] = "X123456";
            _factory.Make();
            Employee fromDB = Employee.FindByXid("X123456");
            Assert.AreEqual("X123456", fromDB.Xid);
        }
 
        [Test]
        public void Xid_should_be_unique()
        {
            _factory.Values["Xid"] = "X123456";
 
            try
            {
                _factory.Make(2);
                Assert.Fail("Xid is not set to be unique");
            }
            catch (Castle.ActiveRecord.Framework.ActiveRecordException ex)
            {
                Assert.That(ExceptionMessageContains(ex, "Violation of UNIQUE KEY constraint"));
            }
        }
 
        [Test]
        public void Search_Should_Search_Xid()
        {
            _factory.Values["Xid"] = "X123456";
            _factory.Make();
            _factory.ResetValues();
            _factory.Make();
 
            Employee[] emps = Employee.Search("X123456");
            Assert.AreEqual(1, emps.Length);
            Assert.AreEqual("X123456", emps[0].Xid);
        }
 
        [Test]
        public void Search_Should_Search_LastName()
        {
            _factory.Values["LastName"] = "MyLast";
            _factory.Make();
            _factory.ResetValues();
            _factory.Make();
 
            Employee[] emps = Employee.Search("MyLast");
            Assert.AreEqual(1, emps.Length);
            Assert.AreEqual("MyLast", emps[0].LastName);
        }
 
        [TearDown]
        public void TearDown()
        {
            DisposeScope();
        }
 
    }

I am looking to improve on this code as I use it, but I’m rather happy with how well it’s working so far.