views:

176

answers:

3

I have a class which has some unit tests, but when I am running tests I would like the class to be created with a different constructor. Something like this:

[TestFixture]
public class MyClass
{
    public MyClass() { /* set up for production */ }

    [TestFixtureConstructor]
    public MyClass() { /* set up for testing */ }

    [Test]
    public void FirstTest()
    {
        // assert some values
    }
}

Is this even possible?

I have considered using a static factory method for creating the class in production (with a private constructor), and a public constructor for the testing framework.

Does anyone have any other solutions?

+8  A: 

You don't do this.

You do not have your tests written inside the class that you use in real code; you write your tests external to the classes. I believe most testing suites have the concept of 'Teardown' and the opposite; to set up the test environment for a given execution.

Noon Silk
100% correct. To the OP - you shouldn't be trying for special "test-only" constructors either. If you need to have a constructor to take in dependencies, and the only thing that using it is tests, that's fine, but that constructor shouldn't be hidden from everyone else. It makes your class more flexible for consumers to pass in the dependencies.
womp
I agree. This is absolutely the wrong way of doing this. Create a separate class and use the Setup and Teardown attributes
lomaxx
+3  A: 

To give a quick example of silky's correct approach:

public class MyClass
{
    // ...
}

// In a different assembly:

[TestFixture]
public class TestMyClass
{
    [SetUp]
    public void SetUp()
    {
        _myClass = new MyClass();
    }

    [Test]
    public void FooReturnsTrue()
    {
        Assert.That(_myClass.Foo(), Is.True);
    }

    // more tests

    private MyClass _myClass;
}
TrueWill
+2  A: 

If you really really want this you can take a look at TestFixtureSetUp.

Here's the introduction:

This attribute is used inside a TestFixture to provide a single set of functions that are performed once prior to executing any of the tests in the fixture. A TestFixture can have only one TestFixtureSetUp method. If more than one is defined the TestFixture will compile successfully but its tests will not run.

Example:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  public class SuccessTests
  {
    [TestFixtureSetUp] public void Init()
    { /* ... */ }

    [TestFixtureTearDown] public void Dispose()
    { /* ... */ }

    [Test] public void Add()
    { /* ... */ }
  }
}

But you should use this with care, or else it defeats the purpose of unit test.

Ngu Soon Hui