Unit Testing Domain Model Objects

In our design of the model of the main area, we have a class called "Category", whose constructor is internal in design. Since the constructor is internal, when writing unit test cases, I cannot create a Category object.

So my question is: is it better to publish the constructor only so that the "Category" class can be tested? Or should I not test this "category", instead I should check the class / method responsible for creating this object?

That

Rajeesh

+6
c # unit-testing tdd domain-driven-design
source share
4 answers

TDD stands for Test- Driven Design, and this means that a constructor cannot really be β€œby design” if you cannot test it.

Think about why it is internal. This will show you how to solve this problem. You do not have to publish a constructor to test it, but you should consider a design that makes it easy to create new instances.

Often, constructors become internal to protect invariants, but you can also achieve the same goal with a public constructor that accepts the required input as constructor parameters.

public class MyClass { private readonly string requiredString; public MyClass(string requiredString) { if (requiredString == null) { throw new ArgumentNullException("requiredString"); } this.requiredString = requiredString; } } 

Note that a combination of the Guard clan and the readonly keyword protect the class invariant. This is often a good alternative to internal constructors.

Another reason for having internal constructors is when you have a Factory method that can return a polymorphic object, but think again, it would be a problem to expose the constructor if that doesn't mean compromising invariants.

The beauty of TDD is that it makes us look good at any design decision and be able to truly justify each of them. Consider the rationale for creating an internal constructor, and then the modfiy API so that the type is easily created.

+5
source share

Do not create a constructor for unit tests only. If you decide from the design point that it should be internal, leave it that way. Check out the classes calling this constructor.

.NET has an InternalsVisibleToAttribute that allows you to expose internal elements for unit tests.

+6
source share

Add

  [assembly: InternalsVisibleTo("UnitTestAssembly")] 

to your AssemblyInfo.cs. Then UnitTestAssembl.dll can call your internal methods. Further information is available here .

+3
source share

You can create a static factory method called

 Category *ConstructCategory_ForUnitTest(); 

with which you can create an object only for testing it.

From the name it is clear that it should not be used outside the testing context, and code analysis can easily detect "illegal" use in the code of a production class.

0
source share

All Articles