Tip – When writing custom assertion methods – Keep your assertion stack trace clean

I have bumped in to a couple of custom assertion methods which lets the assertion stack trace contain the assertion method itself. Hence, if I use, e.g. Testdriven.Net, I might double-click on the wrong line and end up in the assertion method, instead of the test. It’s really easy to prevent this, just add the DebuggerHiddenAttribute (read more) to the assertion method.

Example

First, lets be clear. The taken example is not realistic and there’s already support for array assertions but lets pretend I want an assertion method that asserts string arrays and ensures that:

  • the number of elements are the same
  • the order of the elements are the same

I’m using Galio, MbUnit and Testdriven.net

The test

[TestFixture]
public class DummyTests
{
    [Test]
    public void GetAsSortedStringArray_WhenManyParams_ReturnsSortedStringArray()
    {
        var values = new int[] {0, 4, 5, 1, 3, 2};
        var expectedResult = new[] {"0", "-1", "2", "3", "4", "5"};

        var dummy = new Dummy();
        var sortedStringArray = dummy.GetAsSortedStringArray(values);

        ArrayAssert.AreMatches(expectedResult, sortedStringArray);
    }
}

The test will fail (which is expected in this blogpost) since The expected element number "2" should have value "1" and not "-1"

What is wrong with the test

The implementation of Dummy

public class Dummy
{
    public string[] GetAsSortedStringArray(params int[] values)
    {
        return values.Select(v => v.ToString()).OrderBy(v => v).ToArray();
    }
}

The Assertion method

public static class ArrayAssert
{
    public static void AreMatches(string[] expectedValues, string[] actualValues)
    {
        var numOfExpected = expectedValues.Count();
        var numOfActual = actualValues.Count();

        if (numOfExpected != numOfActual)
            throw new AssertionException(string.Format(
                @"The expected values and the actual values have 
                different number of elements.
                Expected: '{0}'; Actual: '{1}'.", numOfExpected, numOfActual));

        for(var c = 0; c < numOfExpected; c++)
        {
            var expected = expectedValues[c];
            var actual = actualValues[c];

            if(!expected.Equals(actual))
                throw new AssertionException(string.Format(
                    @"The values in element-position '{0}' are not the same.
                    Expected: '{1}'; Actual: '{2}'.", c, expected ?? "", actual ?? ""));
        }
    }
}

What’s wrong?

The result of the assertion will be:

Testdriven.Net – Result
Testdriven.Net - Result - Not friendly

Gallio – Result
Gallio - Result - Not friendly

I have tried to mark the lines that I think pollutes the result. It’s the lines stating something like:

Class1.cs(44,0): at ClassLibrary1.ArrayAssert.AreMatches(String[] expectedValues, String[] actualValues)

This is not of interest. And by adding the attribute DebuggerHidden I will get another assertion result, which in my opinion is slightly more friendly.

The corrected assertion method

public static class ArrayAssert
{
    [DebuggerHidden]
    public static void AreMatches(string[] expectedValues, string[] actualValues)
    {
        ...
    }
}
More friendly assertion result

Testdriven.Net – Result
Testdriven.Net - Results - Friendly

Gallio – Result
Gallio - Results - Friendly

Nothing more to say.

//Daniel

Moq vs Typemock – Simple solution to It.Is(expression)

So I thought I just add one more post about this subject. Previous posts:

As I stated I don’t like the predicate that gives me an object[0], so why not do something about it.

public static class IArgumentsMatcherExtensions
{
    public static void Matching<T>(this IArgumentsMatcher matcher, Predicate<T> verify)
    {
        matcher.Matching(args => verify.Invoke((T)args[0]));
    }
}

With this code I can now write tests like:

[Test, Isolated]
public void TheTest3()
{
    var args = new MyArgsWithoutEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();
    fake.MyMethod(args);

    Isolate.Verify.WasCalledWithArguments(
        () => fake.MyMethod(args)).Matching<IMyArgs>(a1 => a1.Id == 1);
}

Instead of

[Test]
public void TheTest4()
{
    var args = new MyArgsWithoutEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();
    fake.MyMethod(args);

    Isolate.Verify.WasCalledWithArguments(
        () => fake.MyMethod(args)).Matching(x => ((IMyArgs)x[0]).Id == 1);
}

I hope I will see something like this in Typemock in the future.

//Daniel

Moq vs TypeMock – Simple solution to It.IsAny

So I just posted this post where I wanted the It.IsAny syntax in Typemock. Without giving any long thought on this I wrote two simple solutions:

Solution 1

public static class IVerifyHandlerExtensions
{
    public static void WasCalledWithAnyArguments<T>(this IVerifyHandler handler, Action<T> action)
    {
        handler.WasCalledWithAnyArguments(() => action.Invoke(default(T)));
    }
}
[Test, Isolated]
public void TheTest()
{
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();
    fake.MyMethod(new MyArgsWithoutEquals());

    Isolate.Verify.WasCalledWithAnyArguments<MyArgsWithoutEquals>(fake.MyMethod);
}

Solution 2

public static class IsAny<T>
{
    public static T Item = default(T);
}
[Test, Isolated]
public void TheTest2()
{
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();
    fake.MyMethod(new MyArgsWithoutEquals());

    Isolate.Verify.WasCalledWithAnyArguments(() => fake.MyMethod(IsAny<IMyArgs>.Item));
}

As I said. Not much thinking in there so I’m probably missing something. It worked for me. Now I don’t have to type “null” any more.

//Daniel

Moq vs Typemock – It.IsAny & It.Is

I kind of like the It.IsAny syntax and It.IsAny(validation expression) syntax of Moq. So now when I’m in the process of switching to Typemock I really was looking for this kind of API.

I have put together some simple samples to show the difference.

The difference in the APIs

#1

[Test]
public void VerifyCallWithExplicitArguments_WhenSameInstanceArgs_VerifiesOk()
{
    var args = new MyArgsWithoutEquals();
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(args);

    fake.Verify(f => f.MyMethod(args));
}
[Test, Isolated]
public void VerifyCallWithExplicitArguments_WhenSameInstanceArgs_VerifiesOk()
{
    var args = new MyArgsWithoutEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();

    var invoker = new Invoker(fake);
    invoker.Invoke(args);

    Isolate.Verify.WasCalledWithExactArguments(
        () => fake.MyMethod(args));
}

#2

[Test]
public void VerifyCallWithExplicitArguments_WhenOtherInstanceArgs_ThrowsMockException()
{
    var args = new MyArgsWithoutEquals();
    var argsOther = new MyArgsWithoutEquals();
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(argsOther);

    Assert.Throws<MockException>(
        () => fake.Verify(f => f.MyMethod(args)));
}
[Test, Isolated]
public void VerifyCallWithExplicitArguments_WhenOtherInstanceArgs_ThrowsMockException()
{
    var args = new MyArgsWithoutEquals();
    var argsOther = new MyArgsWithoutEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();

    var invoker = new Invoker(fake);
    invoker.Invoke(argsOther);

    Assert.Throws<VerifyException>(
        () => Isolate.Verify.WasCalledWithExactArguments(
            () => fake.MyMethod(args)));
}

#3

[Test]
public void VerifyCallWithExplicitArgumentsAndValues_WhenOtherInstanceArgsWithSameValues_VerifiesOk()
{
    var args = new MyArgsWithoutEquals { Id = 1 };
    var argsOther = new MyArgsWithoutEquals { Id = 1 };
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(argsOther);

    fake.Verify(f => f.MyMethod(It.Is<MyArgsWithoutEquals>(a => a.Id == args.Id)));
}
[Test, Isolated]
public void VerifyCallWithExplicitArgumentsAndValues_WhenOtherInstanceArgsWithSameValues_VerifiesOk()
{
    var args = new MyArgsWithoutEquals { Id = 1 };
    var argsOther = new MyArgsWithoutEquals { Id = 1 };
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();

    var invoker = new Invoker(fake);
    invoker.Invoke(argsOther);

    Isolate.Verify.WasCalledWithArguments(
        () => fake.MyMethod(args)).Matching(a => ((MyArgsWithoutEquals)a[0]).Id == args.Id);
}

#4

[Test]
public void VerifyCallWithExplicitArguments_WhenOtherInstanceArgsWithEqualsImplementation_VerifiesOk()
{
    var args = new MyArgsWithEquals();
    var argsOther = new MyArgsWithEquals();
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(argsOther);

    fake.Verify(f => f.MyMethod(args));
}
[Test, Isolated]
public void VerifyCallWithExplicitArguments_WhenOtherInstanceArgsWithEqualsImplementation_VerifiesOk()
{
    var args = new MyArgsWithEquals();
    var argsOther = new MyArgsWithEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();

    var invoker = new Invoker(fake);
    invoker.Invoke(argsOther);

    Isolate.Verify.WasCalledWithExactArguments(
        () => fake.MyMethod(args));
}

#5

[Test]
public void VerifyCallWithAnyArguments_WhenInstanceOfCorrectType_VerifiesOk()
{
    var args = new MyArgsWithoutEquals();
    var fake = new Mock<MyClassUnderTest>();

    var invoker = new Invoker(fake.Object);
    invoker.Invoke(args);

    fake.Verify(f => f.MyMethod(It.IsAny<MyArgsWithoutEquals>()));
}
[Test, Isolated]
public void VerifyCallWithAnyArguments_WhenInstanceOfCorrectType_VerifiesOk()
{
    var args = new MyArgsWithoutEquals();
    var fake = Isolate.Fake.Instance<MyClassUnderTest>();
            
    var invoker = new Invoker(fake);
    invoker.Invoke(args);

    Isolate.Verify.WasCalledWithAnyArguments(() => fake.MyMethod(null));
}

Test duration

I also spotted something else. The difference in duration of the tests. Even though this isn’t a realistic scenario, since I only have five tests, I thinkt it’s kind of fun to see. It would be interesting to swap in a real scenario where there’s alot of faking going on.
Moq vs Typemock - Test duration

When doing these tests I was consuming:

  • Moq v4.0.10501.6 (what’s with all these decimals. I just wan’t to be able to determine older/never)
  • Typemock v6.0.3.0

I also tested to disable Typemock and to run the Moq test alone. The result was the same.

Download the code here

The conclusions

Conclusion #1
Regarding to the It.IsAny and It.Is(validation expression), the conclusion is that the only API member I’m missing, is the It.IsAny. Why? Because I really don’t like the way I have to pass null to WithAnyArguments, in Typemock. I really hope they implement something similar. And if they have, please correct me.

Conclusion #2
I also would like Typemock to provide me a solution where I don’t have to verify against an object[] as in code example #3 above.

Conclusion #3
I like the way Typemock uses “Fakes” instead of “Mocks”. This since Fakes covers both Stubs and Mocks, while the Moq framework lets Mock represent both Stubs and Mocks, which is somewhat confusing.

So, so far I’m happy with the invested money in Typemock.

//Daniel

Typemock – Beautiful exceptions

So I recently started to use Typemock instead of Moq and I’m currently getting acquainted with the API. I just found something that I really think shows that they are putting in some effort to the product. It’s no fancy feature just something that I think every Mocking-framework should provide: “Informative and guiding exceptions when you use the framework inappropriately.”

Take this for an example:

[Test, Isolated]
public void Execute_WhenNoNotationExistsAndDateIsToday_RegistrationIsAllowed()
{
    var scenario = new RegisterSleepNotationScenario().ConfigureParams(
        p => p.NewSleepNotation = new SleepNotation(new Kid(), Week.Current, DayOfWeek.Monday, 1, 50));
    var sleepNotationsSourceFake = Isolate.Fake.Instance<IEditableObjectSource<SleepNotation>>();
    scenario.SleepNotaionsSource = sleepNotationsSourceFake;

    scenario.Execute();

    Isolate.Verify.WasCalledWithExactArguments(
        () => sleepNotationsSourceFake.Insert(scenario.Params.NewSleepNotation));
}

This test resulted in the following exception from Typemock:

This informative message then lead me to the small change:

var expectedNewSleepNotation = scenario.Params.NewSleepNotation;
Isolate.Verify.WasCalledWithExactArguments(() => sleepNotationsSourceFake.Insert(expectedNewSleepNotation));

Which resulted in a green test and a happy developer, without having to use Google or the Typemock-documentations to search for: “how to consume WasCalledWithExactArguments”. As it should be. Thank you Typemock!

//Daniel

How-to isolate DateTime.Now in your unit tests

Updated: The code for the OverrideDateTimeWithQueue method and the test that consumed it has been updated.

I’m currently working on an application that makes some calculations depending on dates. In one scenario I wanted to ensure that a correct timeintervall is created from DateTime.Now. Since I’m not using TypeMock an easy way is to don’t access DateTime.Now directly in my code, but via instead via a static proxy, to which I can inject code that tells it what dates to return. This is not a new solution, search with Google for eg. “unit test datetime.now” and see for your self.

I also wanted the ability to Queue dates, for the ability to setup a range of expected dates that would be dequeued at each requested for DateTime.Now. One simple implementation I could think of was to let my static proxy implementation use a Func that per default just returns DateTime.Now; but of course can be overridden by the user.

Before we look at the tests, lets give some insight to the domain: With the use of a recorder I can create recordings. Each recording will get a start- and stoptime and will be created when recorder.Stop is invoked. The Recording can then be fetched/accessed via recorder.LastRecording or via an event: RecordingCompleted; raised by the recorder. The Recorder holds StartedAt and StoppedAt timestamps which are used to populate the Recording.

When I want the value of DateTime.Now in my domain, I fetch it from my proxy: DateTimeNow.Value

The Old test

[TestMethod]
public void Start_WhenSecondCall_TimeStampsAreUpdated()
{
	var recorder = RecorderFactoryForTests.Default();
	recorder.Start();
	recorder.Stop();

	DateTimeAsserts.GainsValueBetweenNow(
		() => recorder.StartedAt, recorder.Start);
	Assert.IsNull(recorder.StoppedAt);
}

DateTimeAsserts.GainsValueBetweenNow, ensures that when recorder.Start is invoked a before and after timestamp is stored away and then is the recorder.StartedAt compared against these dates. Not so good, since I can’t isolate the value.

The New test

[TestMethod]
public void Start_WhenSecondCall_TimeStampsAreUpdated()
{
    var dateTimes = new[] { 
            DateTime.Parse("2010-01-01 00:00:00"),
            DateTime.Parse("2010-01-01 00:01:00"),
            DateTime.Parse("2010-01-01 00:02:00") };
    var recorder = RecorderFactoryForTests.Default();

    TestHelper.OverrideDateTimeWithQueue(
        () =>
        {
            recorder.Start();
            recorder.Stop();
            recorder.Start();
        }, dateTimes);

    Assert.AreEqual(dateTimes[2], recorder.StartedAt);
    Assert.IsNull(recorder.StoppedAt);
}

Now, the first item in dateTimes will be consumed by recorder.Start() and assigned to recorder.StartedAt. The second element will be assigned to StoppedAt in recorder.Stop() and the last value will be assigned to recorder.StartedAt when the last recorder.Start() call is executed.

The test will of course break if let’s say the first call to recorder.Start() invokes DateTimeNow.Value two times. Another way to write the test is:

[TestMethod]
public void Start_WhenSecondCall_TimeStampsAreUpdated()
{
    var expectedStartedAt = DateTime.Parse("2010-01-01 00:02:00");
    var recorder = RecorderFactoryForTests.Default();

    recorder.Start();
    recorder.Stop();

    DateTimeNow.Set(() => expectedStartedAt);
    recorder.Start();

    Assert.AreEqual(expectedStartedAt, recorder.StartedAt);
    Assert.IsNull(recorder.StoppedAt);
}

Code for DateTimeNow

public static class DateTimeNow
{
    private static readonly object _lock;
    private static Func<DateTime> DateTimeNowFunc { get; set; }

    static DateTimeNow()
    {
        _lock = new object();
        Reset();
    }

    public static DateTime Value
    {
        get { return DateTimeNowFunc.Invoke(); }
    }

    public static void Set(Func<DateTime> dateTimeNowFunc)
    {
        lock (_lock)
        {
            DateTimeNowFunc = dateTimeNowFunc;
        }
    }

    public static void Reset()
    {
        Set(() => DateTime.Now);
    }
}

Code for the TestHelper.OverrideDateTimeWithQueue

public static void OverrideDateTimeWithQueue(Action action, params DateTime[] expectedDates)
{
    var queuedDates = new Queue<DateTime>(expectedDates);

    try
    {
        DateTimeNow.Set(queuedDates.Dequeue);
        action.Invoke();
    }
    finally
    {
        DateTimeNow.Reset();
    }
}

That’s it.

//Daniel

Faking API for stubs and mocks

Just for fun I started to build my own API for taking care of stubbing and mocking while writing my tests. It wasn’t all for fun, since I didn’t like the API of the Moq-framework (read earlier writings about this) I thought that I could wrap Moq in my own API. Since I’m not consuming all the functionality of the Moq-framework, I will get a more slim API that doesn’t tangle stubs and mocks. It will also make it possible for me to switch (why I would like this I really don’t know) for another framework than Moq; or actually build my own instead of just a wrapper.

The result? Well as I see it it all start with the intent of faking something (use a stand-in); either as a simple stub or a mock. And the stub and mock should have different configuration API.

The result so far (since I add functionality when I need it)

var newUserAccount = UserAccountFactoryForTests.CreateValidUserAccount();
var entityStoreMock = Fake<IEntityStore>.Mock();
var componentContainerStub = Fake<IoCContainer>.Stub()
    .Returns(c => c.Resolve<IEntityStore>(), entityStoreMock.MockedObject);
var service = new SecurityService { ServicesIoCContainer = componentContainerStub.StubbedObject };

The code can be downloaded from here.

//Daniel

How-to write tests for extension methods without Typemock

Ok, I’m not a happy owner of Typemock, hence I can’t use it to mock extension methods.

I will show you two really simple workarrounds for achieving this.

I have some simple extension methods that extends IQueryable. One of the extensions is responsible for checking if a certain username allready is taken.
The extension method

public static bool UsernameIsTaken(this IQueryable<UserAccount> userAccounts, string username)
{
    return
        userAccounts.Where(
            u =>
            u.Username.Equals(username, StringComparison.InvariantCultureIgnoreCase)).Count() > 0;
}

As I’m using the Moq-framework for setting up my fakes (in this case stub, see earlier post) I will get an exception.

The test as I want it (which doesn’t work) looks like this

[TestMethod]
public void Validate_TakenUsername_GivesViolation()
{
    var userAccount = UserAccountFactoryForTests.CreateValidUserAccount();
    var userAccountStoreStub = Fake.Stub.New<IQueryable<UserAccount>>();
    Fake.Stub.Returns(userAccountStoreStub, stub => stub.UsernameIsTaken(userAccount.Username), true);

    var validator = new NewUserAccountValidator(userAccountStoreStub);
    var validationResult = validator.Validate(userAccount);

    Assert.AreEqual(TimeTracking.Domain.Resources.UserAccountValidationMessages.UsernameIsAllreadyTaken, validationResult.GetViolationsByMembername("Username")[0].ErrorMessage);
}

This stub is fairly simple to replace manually. All I need is a generic List of UserAccount that contains an instance of an useraccount that has the same username as the username I’m validating.

Solution 1 – Setup a generic list and pass it as IQueryable

[TestMethod]
public void Validate_TakenUsername_GivesViolation()
{
    var userAccount = UserAccountFactoryForTests.CreateValidUserAccount();
    var userAccountStoreStub = new List<UserAccount>
                                   {
                                       UserAccountFactoryForTests.CreateValidUserAccount()
                                   }.AsQueryable();
    
    var validator = new NewUserAccountValidator(userAccountStoreStub);
    var validationResult = validator.Validate(userAccount);

    Assert.AreEqual(TimeTracking.Domain.Resources.UserAccountValidationMessages.UsernameIsAllreadyTaken, validationResult.GetViolationsByMembername("Username")[0].ErrorMessage);
}

This time I was lucky, since the extension method was on the IQueryable, but what if it was something that is totally custom? Just let the extension method consume something that you can stub. In this case, e.g., a Func (see Daniel Cazzulino’s blog).

Solution 2 – Let the extension method consume something you can stub

public static class UserAccountQueries
{
    public static Func<IQueryable<UserAccount>, string, bool> userNameIsTaken = (userAccounts, username) =>
        userAccounts.Where(
                u =>
                u.Username.Equals(username, StringComparison.InvariantCultureIgnoreCase)).Count() > 0;

    public static bool UsernameIsTaken(this IQueryable<UserAccount> userAccounts, string username)
    {
        return userNameIsTaken(userAccounts, username);
    }
}
[TestMethod]
public void Validate_TakenUsername_GivesViolation()
{
    var userAccount = UserAccountFactoryForTests.CreateValidUserAccount();
    UserAccountQueries.userNameIsTaken = (stub, username) => true;

    var validator = new NewUserAccountValidator(new List<UserAccount>().AsQueryable());
    var validationResult = validator.Validate(userAccount);

    Assert.AreEqual(TimeTracking.Domain.Resources.UserAccountValidationMessages.UsernameIsAllreadyTaken, validationResult.GetViolationsByMembername("Username")[0].ErrorMessage);
}

In my scenario I used solution 1, but in the future I will probably refactor away my code from the extension methods.

//Daniel

The Moq, mockingframework, and the tangling of Stubs and Mocks

When I need the powers of a Faking-framework I use the Moq-framework, which I use when I feel that it is to much work for creating a manual Fake (which I only do with stubs). There’s one thing that I really don’t like with Moq, the tangling of Mocks and Stubs. I like to see them as follows:

Fakes

  • Stubs (is used to make interaction work and to return or throw exceptions etc.)
  • Mocks (is used to assert against by putting demands/expectations on the interaction)
  • This is why I wrote “Faking-framework” above. A stub is a fake and a mock is a fake but a mock is not a stub and a stub is not a mock. Glad that we sorted that out!

    Don’t get me wrong here, I like the Moq-framework, but what I would like to see in it is a separation of stubs and mocks. The API should let you clearly create a stub or a mock. You shouldn’t be able to turn a stub into a mock. When creating the stub, a class named Mock is confusing and missleading hence should not be used.

    Look at the following simple test. I have a shoppingcart for a customer and the cart uses a pricelocator to lookup the prices of the products that I’m adding. The price is determined by looking at the customer, the product and the quantity. In the test I create a stub for my pricelocator, so that I’m sure of the prices it will return. I stub the pricelocator so that the test can query it for two different products for the same customer. Then I add two items to the shoppingcart, which will use the pricelocator when I invoke the GetTotal-function on my shoppingcart.

    The test

    [TestClass]
    public class ShoppingCartTests
    {
        [TestMethod]
        public void GetTotal_TwoValidShoppingCartItems_GivesTotal()
        {
            const string customerNo = "2010-1";
            var item1 = new { CustomerNo = customerNo, ProductNo = "P01-01-00001", Quantity = 2, Result = 101.50M };
            var item2 = new { CustomerNo = customerNo, ProductNo = "P01-01-00002", Quantity = 3, Result = 99.75M };
    
            var expectedTotal = item1.Result + item2.Result;
            var priceLocatorStub = GetPriceLocatorStub(item1, item2);
    
            var shoppingCart = new ShoppingCart(customerNo) { PriceLocator = priceLocatorStub };
            shoppingCart.AddProduct(item1.ProductNo, item1.Quantity);
            shoppingCart.AddProduct(item2.ProductNo, item2.Quantity);
            var actualTotal = shoppingCart.GetTotal();
    
            Assert.AreEqual(expectedTotal, actualTotal);
        }
    
        private static IPriceLocator GetPriceLocatorStub(params object[] items)
        {
            var priceLocatorStub = new Moq.Mock<IPriceLocator>();
    
            foreach (var item in items)
            {
                var tmp = TypeCaster.CastAnonymous(item, new { CustomerNo = "", ProductNo = "", Quantity = 0, Result = 0M });
    
                priceLocatorStub
                    .Setup(pl => pl.LookupPrice(
                                     tmp.CustomerNo,
                                     tmp.ProductNo,
                                     tmp.Quantity)).Returns(tmp.Result);
            }
    
            return priceLocatorStub.Object;
        }
    }
    

    What if I add a expectation to my stub? It is possible, but should it be? Yes it’s possible. With the little change of adding “.AtMost(0)” below, I have created an mock and totally changed the semantics, hence the Assert should change to, but that’s not the point in this blog post. The point is that I think the Moq guys should keep the mocks and stubs API’s sepparated, so when I create a stub I can’t add expectations.

    priceLocatorStub
        .Setup(pl => pl.LookupPrice(
                         tmp.CustomerNo,
                         tmp.ProductNo,
                         tmp.Quantity)).Returns(tmp.Result).AtMost(0);
    

    The changes I want are:

    Instead of:

    var stub = new Mock();
    

    I want:

    var stub = new Stub();
    

    and not being able to add e.g. AtMost-expectations to the Stub.

    Even if this change will not come, I will continue to use the Moq-framework.

    To finnish of, I would like to point out that I think this missuse of the terms mocks and mocking is common amongst developers; who gladly uses variablenames like “*Mock” when they actually are creating a stub; who frequently speaks in terms of mocks, when they actually are using stubs.

    The complete sourcecode can be downloaded from here.

    //Daniel

    How-to test a project that is focused on SSIS

    How-to test a project that is focused on SSIS
    Recently I have been working in a project where SSIS is the primary technology used for solve a business case where focus lies on data-processing. Normally I work with plain C# code and I like test driven development and I like the bi-product that comes with TDD – the unit tests and in the longer run – the integration tests. In this little article I will go through the steps needed to setup a fairly simple but yet effective testing solution for SSIS-development.

    All C# code shall be placed in a separate assembly and hosted in GAC
    First of all: “All C# code that is written I script-components and script-tasks etc. should lie in a separate C#-assembly and should be consumed via the global assembly cache (GAC).” The C# code contained in the SSIS-packages should only place calls to C# code in the external assembly/assemblies. By taking this design decision, you could easily write tests for your code.

    Load and run your packages via code
    Ok, that was the obvious decision, now what could be done to test our packages? We need a way to execute our packages and test the outcome. The first step is to configure the packages to be deployed to a certain directory whenever the Integration services project is built. This is achieved by tweaking the “Deployment utility settings” under properties of the SSIS-project. Activate it by setting “CreateDeploymentUtility” to true and to specify a path for “DeploymentOutputPath”.

    In our integration test project we kicked the packages using simple “load and run technique” which you could read up on here (http://msdn.microsoft.com/en-us/library/ms403355.aspx).

    Make the package-execution configurable
    For ease of setting up different environments (like different developer machines or build servers) I made a Package-executor that was configurable from the app-config.

    <ssisPackageExecutor
      xmlConfigFile="C:\ProjectX\SSIS-Config\CommonConfig-Test.dtsConfig">
      <packages>
        <package name="PackageOne"
                 locationType="Filesystem"
                 packagelocation="C:\ProjectX\Packages\PackageOne.dtsx" />
        <package name="PackageTwo"
                 locationType="Filesystem"
                 packagelocation="C:\ProjectX\Packages\PackageTwo.dtsx" />
      </packages>
    </ssisPackageExecutor>
    

    The attribute “xmlConfigFile” above is used by the Package-executor to inject configurations that are valid for testing purposes. E.g: Point a connection-string to a specific Test-database.

    All that was left was to make a simple SSIS-assert class (which uses the Package-executor) on which you could call, e.g:

    SSISAssert.SuccessfulPackage("PackageOne");
    SSISAssert.FailedPackage("PackageTwo");
    

    After the execution of the package you “just” have to write tests that check the database, filesystem etc. for correct changes.

    Setting up a database automatically
    To make the tests run smoothly you need to have the Test-database setup automatically. One way to achieve this is to make use of script-files that are executed on a certain database. To achieve this all tables, views, functions, stored-procedures etc. needs to be scripted and placed on a disk. I made a simple database installer that checks for version-folders in a certain script-folder repository. If a certain folder should be installed/executed and in what order is configurable in the app-config (see below for example). So the script-folder contained subfolders where each subfolder represented a certain version of the database. For testing purposes I added a test-version folder that contained scripts necessary for setting up the Test-database with specific test tables. Theses specific test-scripts where not executed/installed in the Normal-database. The custom database installer that I build was configurable so that you could install several databases at the same time. This made it easy for each developer to have a Test-database and a Normal-database on their machines.
    The database installer made use of Sql-Server Management Objects (SMO) to execute the scripts and the Test-database was initialized once per assembly. If a certain test required certain test-data in the database, initialize and cleanup methods (using attributes [TestInitialize] and [TestCleanup]) in the test-class called stored-procedure (which was installed/created by a script in the test-version-folder); one for initialization of test-data for the specific test and one for clean up.
    The Configuration looked like this:

    <databaseInstaller>
      <setups>
        <setupInfo name="Normal"
                   connectionStringName="NormalDb"
                   scriptFolderPath="C:\ProjectX\Scripts"
                   versions="initialize;v1"/>
        <setupInfo name="Test"
                   connectionStringName="TestDb"
                   scriptFolderPath="C:\ProjectX\Scripts"
                   versions="initialize;v1;vTest"/>
        </setups>
    </databaseInstaller>
    

    The script-version-folders are applied in the order that they are listed above in the “versions” attribute. If a folder is not present in the attribute but on disk, it will not be executed/installed.

    That’s it. Happy testing.

    //Daniel