MbUnit TypeFixture
This is the first of series of posts I'll be running on MbUnit, I'll focus on v2 first and then show an example in v3. I won't focus on RowTest as this is a popular feature and is well known both by the MbUnit audience and by other frameworks. For the opening post I'll focus on the TypeFixture, let's take a look at the code.
1: using System;
2: using System.Collections;
3: using MbUnit.Framework;
4:
5: [TypeFixture(typeof(IEnumerable))]
6: public class TypeFixtureExample
7: { 8: [Provider(typeof(IEnumerable))]
9: public ArrayList ProviderEmptyArrayList()
10: { 11: return new ArrayList();
12: }
13:
14: [Provider(typeof(IEnumerable))]
15: public ArrayList ProviderArrayList()
16: { 17: ArrayList list = new ArrayList();
18: list.Add(0);
19: list.Add(1);
20: return list;
21: }
22:
23: [Test]
24: [ExpectedException(typeof(InvalidOperationException))]
25: public void CurrentCalledBeforeMoveNext(IEnumerable en)
26: { 27: IEnumerator er = en.GetEnumerator();
28: object p = er.Current;
29: }
30:
31: [Test]
32: [ExpectedException(typeof(InvalidOperationException))]
33: public void CurrentCalledAfterFinishedMoveNext(IEnumerable en)
34: { 35: IEnumerator er = en.GetEnumerator();
36: while (er.MoveNext());
37: object p = er.Current;
38: }
39: }
We have two tests that will run on both methods that are decorated by the Provider attribute, each provider set's up an ArrayList as our target type and each test runs against both providers. Each provider seeds the test method, you could also define one provider as your target type and any number of tests against that provider. If you want to break up your tests into reusable parts then you could do the following.
1: using System.Collections;
2: using MbUnit.Framework;
3:
4: public class ArrayListFactory
5: { 6: [Factory]
7: public ArrayList ProviderEmptyArrayList
8: { 9: get { return new ArrayList(); } 10: }
11:
12: [Factory]
13: public ArrayList ProviderArrayList
14: { 15: get
16: { 17: ArrayList list = new ArrayList();
18: list.Add(0);
19: list.Add(1);
20: return list;
21: }
22: }
23: }
and use these as follows
1: using System;
2: using System.Collections;
3: using MbUnit.Framework;
4:
5: [TypeFixture(typeof(IEnumerable))]
6: [ProviderFactory(typeof(ArrayListFactory), typeof(IEnumerable))]
7: public class ProviderFactoryTest
8: { 9: [Test]
10: [ExpectedException(typeof(InvalidOperationException))]
11: public void CurrentCalledBeforeMoveNext(IEnumerable en)
12: { 13: IEnumerator er = en.GetEnumerator();
14: object p = er.Current;
15: }
16:
17: [Test]
18: [ExpectedException(typeof(InvalidOperationException))]
19: public void CurrentCalledAfterFinishedMoveNext(IEnumerable en)
20: { 21: IEnumerator er = en.GetEnumerator();
22: while (er.MoveNext()) ;
23: object p = er.Current;
24: }
25: }
Here we break out the providers into Factories and referance them in our test using the ProviderFactory attribute. So unlike our first test the Providers are isolated from the test and reusable across other tests however we can still seed our tests as before.
Let's take a look at how MbUnit v3 does this.
1: using System.Collections.Generic;
2: using MbUnit.Framework;
3:
4: public class TypeFixtureExample
5: { 6: public static IEnumerable<IEnumerable> GetInstances()
7: { 8: yield return new ArrayList();
9: yield return new ArrayList { 0, 1 }; 10: }
11:
12: [Factory("GetInstances")] 13: public IEnumerable Instance;
14:
15: [Test]
16: [ExpectedException(typeof(InvalidOperationException))]
17: public void CurrentCalledBeforeMoveNext()
18: { 19: var er = Instance.GetEnumerator();
20: var p = er.Current;
21: }
22:
23: [Test]
24: [ExpectedException(typeof(InvalidOperationException))]
25: public void CurrentCalledAfterFinishedMoveNext()
26: { 27: var er = Instance.GetEnumerator();
28: while (er.MoveNext()) ;
29: var p = er.Current;
30: }
31: }
V3 has done away with the Provider attribute, we use Factory attributes as before but no longer need the ProviderFactory attribute as v3 is a little cleverer at wiring up tthe data. Our type tester methods remain the same however we seed them using the Factory attribute, this like the v2 attribute will create and hold test data for us. In this example the Factory attribute creates a enumerable list of our type along with seeded data. The GetInstances method plays the role of the Provider methods in the v2 example, we are using some 3.5 sugar to shorten the syntax here but the principle of seeded types remains the same.