How do I mock/fake/replace/stub a base class at unit-test time in C#?

Posted by MatthewMartin on Stack Overflow See other posts from Stack Overflow or by MatthewMartin
Published on 2010-03-23T19:47:48Z Indexed on 2010/03/24 12:43 UTC
Read the original article Hit count: 151

Filed under:
|

UPDATE: I've changed the wording of the question. Previously it was a yes/no question about if a base class could be changed at runtime.

I may be working on mission impossible here, but I seem to be getting close. I want to extend a ASP.NET control, and I want my code to be unit testable. Also, I'd like to be able to fake behaviors of a real Label (namely things like ID generation, etc), which a real Label can't do in an nUnit host.

Here a working example that makes assertions on something that depends on a real base class and something that doesn't-- in a more realistic unit test, the test would depend on both --i.e. an ID existing and some custom behavior.

Anyhow the code says it better than I can:

public class LabelWrapper : Label //Runtime
//public class LabelWrapper : FakeLabel //Unit Test time
{
    private readonly LabelLogic logic= new LabelLogic();

    public override string Text
    {
        get
        {
            return logic.ProcessGetText(base.Text);
        }
        set
        {
            base.Text=logic.ProcessSetText(value);
        }
    }
}

//Ugh, now I have to test FakeLabelWrapper
public class FakeLabelWrapper : FakeLabel //Unit Test time
{
    private readonly LabelLogic logic= new LabelLogic();

    public override string Text
    {
        get
        {
            return logic.ProcessGetText(base.Text);
        }
        set
        {
            base.Text=logic.ProcessSetText(value);
        }
    }
}

[TestFixture]
public class UnitTest
{
    [Test]
    public void Test()
    {
        //Wish this was LabelWrapper label = new LabelWrapper(new FakeBase())
        LabelWrapper label = new LabelWrapper();
        //FakeLabelWrapper label = new FakeLabelWrapper();
        label.Text = "ToUpper";
        Assert.AreEqual("TOUPPER",label.Text);
        StringWriter stringWriter = new StringWriter();
        HtmlTextWriter writer = new HtmlTextWriter(stringWriter);
        label.RenderControl(writer);
        Assert.AreEqual(1,label.ID);
        Assert.AreEqual("<span>TOUPPER</span>", stringWriter.ToString());
    }
}

public class FakeLabel
{
    virtual public string Text { get; set; }
    public void RenderControl(TextWriter writer)
    {
        writer.Write("<span>" + Text + "</span>");
    }
}

//System Under Test
internal class LabelLogic
{
    internal string ProcessGetText(string value)
    {
        return value.ToUpper();
    }

    internal string ProcessSetText(string value)
    {
        return value.ToUpper();
    }
}

© Stack Overflow or respective owner

Related posts about c#

Related posts about unit-testing