Running a Sql Script to Insert Lookup Data For Tests From C#

Filed Under (.Net, Unit Testing) by John Miller on 14-03-2009

Tagged Under : , , ,

Earlier this week I needed a way to insert test data into my database that was being regenerated at the start of each test fixture. For most scripts, you can use a simple command with CommandText to get the job done. But this doesn’t work with certain Sql statements, such as GO. Luckily, I stumbled across Microsoft’s Sql Server Management classes which turned out to be exactly what I was looking for.

To use them, we first need to create references to the Microsoft.SqlServer.Smo and Microsoft.SqlServer.ConnectionInfo assemblies.

CreateRef1

CreateRef2

Now, we need to reference those namespaces in our code file.

using System.Data.SqlClient;
using System.IO;
using Microsoft.SqlServer.Management.Smo;
using Microsoft.SqlServer.Management.Common;

 

And now for the code to actually run the script. (I’m calling this method from within RebuildDatabase() which is called in the establish_context(), or [TestFixtureSetup], method of the repository tests.)

public void InsertTestData()
{
    using (var conn = new SqlConnection("<connection string>"))
    {
        FileInfo fileInfo = new FileInfo(@"Sql\InsertSeedData.sql");
        var sql = fileInfo.OpenText().ReadToEnd();
        Server server = new Server(new ServerConnection(conn));
        server.ConnectionContext.ExecuteNonQuery(sql);
    }
}

It’s worth noting that I’m including the Sql script that’s being executed here as a linked file inside the project. The physical file is actually located in an upper level directory outside of the project. Including it as a linked file makes sure that the script is included when the test dlls are being ran. (Just be sure to set the “Copy to Output Directory” property of the file to True in Visual Studio.) Alternatively, you could also you an absolute path to point to your Sql script.

DotNetKicks Image

Share/Save/Bookmark

Testing for Expected Exceptions Without Compromising BDD Conventions

Filed Under (.Net, Unit Testing) by John Miller on 10-02-2009

Tagged Under : , , ,

Today I decided to relearn some of the BDD concepts I picked up at the end of last year and ran into a scenario where I needed to test that a specific type of exception was being thrown by a method. The simple way to do this is to decorate your test method with an ExpectedException attribute, but that forces you to combine the Act/Assert parts of your test.

Not happy with that solution I decided that I would rather catch the exception in one part of my test and validate it’s type later. In the end, I created a helper class to do some of the work:

public class ExceptionTestHelper
{
    public static Exception CatchException(Action action)
    {
        try
        {
            action.Invoke();
        }
        catch (Exception ex)
        {
            return ex;
        }

        return null;
    }
}

Pretty simple. And now our tests seem a little more natural.

[TestFixture]
public class When_asked_to_get_a_users_goals_using_an_invalid_user_id
    : GoalsServiceTestBase
{
    private Exception caughtException;

    protected override void because()
    {
        base.because();
        caughtException =
            ExceptionTestHelper.CatchException(
                () => goalsService.GetGoalsForUser(-1));
    }

    [Test]
    public void should_throw_an_argument_exception()
    {
        Assert.That(caughtException,
            Is.InstanceOfType(typeof(ArgumentException)));
    }
 }

 

public abstract class GoalsServiceTestBase : TestBase

{
    protected IGoalsRepository stubGoalsRepository;
    protected IGoalsService goalsService;
    protected Goal stubGoal;

    protected override void  establish_context()
    {
        base.establish_context();
        stubGoalsRepository =
            MockRepository.GenerateStub<IGoalsRepository>();
        goalsService = new GoalsService(stubGoalsRepository);
        stubGoal = new Goal();
    }
}
[TestFixture]
public abstract class TestBase
{
    [SetUp]
    public void setup()
    {
        establish_context();
        because();
    }

    protected virtual void establish_context()
    { }

    protected virtual void because()
    { }
}

At first glance I like it. Although I’m sure that someone out there that may have a better solution that still sticks with our BDD approach.

DotNetKicks Image

Share/Save/Bookmark

Absolute Paths for Code Coverage Artifacts in MSTest

Filed Under (.Net, Unit Testing) by John Miller on 07-12-2008

Tagged Under : , , ,

I ran into a case today where one of our unit tests was failing when we ran it, but would pass when we debugged it. We’re using MSTest and had recently branched the project in TFS, and I was working on changes in the new branch. We were getting a “method not found” error when running the test which immediately made me think that Visual Studio was using a cached version of the class under test.

It turned out that the culprit was our use of Code Coverage. While working in the initial branch, we had turned on Code Coverage for the project we were testing. However Visual Studio will look for the project dll two different ways depending on your solution structure. If the project is in the solution directory, it will look for the dll using a relative path such as:

<Solution Directory>project1\bin\debug\project1.dll

However, if you like to keep your solutions separate from the projects like we are (we have a separate folder containing all our solutions), it will use an absolute path to find the dll.

C:\Source\project1\bin\debug\project1.dll

This worked fine until we created a new branch of the code. I mapped the new branch to a different location locally and Visual Studio was still using the old version when running Code Coverage. (Which why it would pass when we debugged the tests, Code Coverage isn’t run when you debug tests.)

So after branching, your Code Coverage list could potentially look something like this.

CodeCoverage

Note that there’s two ClassLibrary1.dll artifacts in the list. The first actually points to the initial branch of the code. The second points to the newly created branch. Unchecking the first and checking the second fixes the issue.

On a side note, I can’t wait to drop MSTest and go back to NUnit!

kick it on DotNetKicks.com

Share/Save/Bookmark