Steven Evers
Steven Evers

Reputation: 17196

nunit setup/teardown not working?

Ok, I've got a strange problem. I am testing a usercontrol and have code like this:

[TestFixture]
public myTestClass : UserControl
{
    MyControl m_Control;

    [Test]
    public void TestMyControl()
    {
        m_Control = new MyControl();
        this.Controls.Add(m_Control);

        Assert.That(/*SomethingOrOther*/)
    }
}

This works fine, but when I change it to:

[TestFixture]
public myTestClass : UserControl
{
    MyControl m_Control;

    [Setup]
    public void Setup()
    {
        m_Control = new MyControl();
        this.Controls.Add(m_Control);
    }

    [TearDown]
    public void TearDown()
    {
        this.Controls.Clear();
    }

    [Test]
    public void TestMyControl()
    {
        Assert.That(/*SomethingOrOther*/);
    }
}

I get an Object Reference Not Set To An Instance of an Object. I even output to the console to ensure that the setup/teardown were running at the correct times, and they were... but still it isn't newing up the usercontrols.

edit> The exact code is:

[TestFixture]
public class MoneyBoxTests : UserControl
{
    private MoneyBox m_MoneyBox;
    private TextBox m_TextBox;

    #region "Setup/TearDown"
    [SetUp]
    public void Setup()
    {
        MoneyBox m_MoneyBox = new MoneyBox();
        TextBox m_TextBox = new TextBox();

        this.Controls.Add(m_MoneyBox);
        this.Controls.Add(m_TextBox);
    }

    [TearDown]
    public void TearDown()
    {
        this.Controls.Clear();
    }
    #endregion

    [Test]
    public void AmountConvertsToDollarsOnLeave()
    {
        m_MoneyBox.Focus();
        m_MoneyBox.Text = "100";
        m_TextBox.Focus();

        Assert.That(m_MoneyBox.Text, Is.EqualTo("$100.00"), "Text isn't $100.00");
    }

    [Test]
    public void AmountStaysANumberAfterConvertToDollars()
    {
        m_MoneyBox.Focus();
        m_MoneyBox.Text = "100";
        m_TextBox.Focus();

        Assert.That(m_MoneyBox.Amount, Is.EqualTo(100), "Amount isn't 100");
    }
}

I get the exception(s) at the respective m_MoneyBox.Focus() calls.

Solved - See Joseph's comments

Upvotes: 3

Views: 5962

Answers (3)

Zam
Zam

Reputation: 21

I had exactly the same issue, so my apologies for answer to this old post. The problem in your code (and mine) is that you are creating 2 different instances for MoneyBox and 2 more for TextBox. So, the initial assignation inside Setup, is valid only for Setup method and out_of_scope in the test methods.

Inside the Setup method you should use:

m_MoneyBox = new MoneyBox(); //GOOD
m_TextBox = new TextBox();  //GOOD

instead of

MoneyBox m_MoneyBox = new MoneyBox();  //BAD
TextBox m_TextBox = new TextBox();  //BAD

Just for anyone that could need it again

Upvotes: 2

Joseph
Joseph

Reputation: 25513

I created a test case with exactly the same layout you presented here, but with a TextBox instead of a MyControl. I also added a constructor and a deconstructor and outputted all the various stages to the console to see the sequence of events. However, I never got an object reference exception.

In case you are interested, the sequence was [constructor called], [setup called], [test called], [tear down called]. The deconstruction never output anything to the screen for some reason.

My original thought was that the Controls property on myTestClass would not be initialized, but on my test it was, so I think it has something to do with your MyControl construction.

edit> I added the focus on my TextBox in my unit test as well but still no exception. Does your MoneyBox have any event handling going on behind the scenes during the Focus? That might be your culprit.

Upvotes: 3

Jon Skeet
Jon Skeet

Reputation: 1500135

You haven't said where you're getting the exception, which would help - what does the stack trace look like?

It's very odd (IME) to derive from UserControl when you create a test fixture. Aside from anything else, I don't know that NUnit is going to call Dispose for you at any appropriate point... what's the purpose of it here? Can you not make your tests run with a "plain" test fixture?

Upvotes: 3

Related Questions