Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing a class with an internal constructor

Tags:

I have a class called "Session" which exposes several public methods. I'd like to Unit Test these, however in production I need to control instantiation of "Session" objects, so delegate construction to to a SessionManager class and have made the Session's constructor internal.

I'd ideally like to test the Session class in isolation from the SessionManager which creates it/them to prove that the public interfaces exposed by the Session work as expected - but can't instantiate a Session from a test without using a SessionManager making my tests more complicated/less useful than they need to be.

What's the best way to deal with this?

Cheers,

Lenny.

like image 651
Leonard H. Martin Avatar asked Nov 06 '09 23:11

Leonard H. Martin


People also ask

How do you test a constructor in unit testing?

To test that a constructor does its job (of making the class invariant true), you have to first use the constructor in creating a new object and then test that every field of the object has the correct value. Yes, you need need an assertEquals call for each field.

Can constructor be internal?

Constructor code or any internal method used only by constructor are not included in final code. A constructor can be either public or internal. A internal constructor marks the contract as abstract. In case, no constructor is defined, a default constructor is present in the contract.

Should we write unit test for constructors?

because your operation should fail if that object is null which makes sense the "behavior" fails and we should unit test that rather the actual constructors.

Can a test class have a constructor C#?

You can test the constructor of your object in a test method [Test]. Object in the [TestInitialize] can be to setup your persistance storage or to prepare value that the object tested will used in the tests.


3 Answers

Nothing prevents you from testing internals. Simply make the internals of your code visible to the test suite, by using the InternalsVisibleTo attribute: in the AssemblyInfo, add

[assembly:InternalsVisibleTo("TestSuiteAssembly")]
like image 147
Mathias Avatar answered Sep 23 '22 16:09

Mathias


You could just make your unit test class inherit from Session (assuming your test framework doesn't require that you inherit from a specific class). For instance, with NUnit :

[TestFixture]
public class SessionTest : Session
{
    public SessionTest()
        : base() // call protected constructor
    {
    }

    [Test]
    public void TestSomething()
    {
    }

}
like image 25
Thomas Levesque Avatar answered Sep 22 '22 16:09

Thomas Levesque


Alternatively, as a workaround, you could just create a TestSession that inherits from Session and exposes a public constructor. Inside your unit-test you then use the TestSession which basically does the same as the original Session object.

public class TestSession : Session
{

   public TestSession() : base()
   {

   }

}
like image 22
Juri Avatar answered Sep 23 '22 16:09

Juri