Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a unit test for "T must be a reference type"?

Consider:

class MyClass<T> where T : class
{
}

In that case, the where clause is enforcing a specification that MyClass is only a generic of a reference type.

Ideally I should have a unit test that tests this specification. However, this unit test obviously won't work, but it explains what I'm trying to accomplish:

[Test]
[DoesNotCompile()]
public void T_must_be_a_reference_type()
{
    var test = new MyClass<int>();
}

What can I do to test a spec that's implemented by not allowing the code to compile?

EDIT:

More info: Ok, so my reasoning for doing this (haha) is that I've been following a TDD methodology, in which you can't write any code unless you have a failing unit test. Let's say you had this:

class MyClass<T> { }

What test can you write that would fail unless T were a class? Something like default(T) == null?

Further EDIT:

So after a "root cause analysis" on this, the problem is that I was relying on default(T) being null in a consumer of this class, in an implicit way. I was able to refactor that consumer code into another class, and specify a generic type restriction there (restricting it to class) which effectively makes that code not compile if someone were to remove the restriction on the class I'm talking about above.

like image 847
Scott Whitlock Avatar asked Oct 27 '10 15:10

Scott Whitlock


People also ask

How should unit tests be written?

Follow Arrange, Act, Assert The AAA is a general approach to writing more readable unit tests. In the first step, you arrange things up for testing. It's where you set variables, instantiate objects, and do the rest of the required setup for the test to run. During this step, you also define the expected result.

What must be tested by a unit test?

A unit test is a way of testing a unit - the smallest piece of code that can be logically isolated in a system. In most programming languages, that is a function, a subroutine, a method or property. The isolated part of the definition is important.

What are the three steps in a unit test?

The idea is to develop a unit test by following these 3 simple steps: Arrange – setup the testing objects and prepare the prerequisites for your test. Act – perform the actual work of the test. Assert – verify the result.

What is a unit test example?

A Real-world ExampleThe above unit test “asserts” that 5 + 10 is equal to 15. If the Add function returns anything else Assert. IsEqual result in error and the test case will fail. After you write your test cases, you will run them to verify that everything is working correctly.


1 Answers

Why would you need a unit test for this? Do you write a unit test for a method such as

public void Foo(string x)

to check that it can only take strings, and not integers? If not, what do you see as the difference?

EDIT: Just to be slightly less whimsical: in this case the spec is validated by the declaration. Tests should generally test behaviour. That's one of the things I like about Code Contracts: I don't feel any need to unit test the contracts unless they express something complicated - in which case it's that complexity that I'd be testing, not the "contracts are enforced" bit.

EDIT: To respond to the question edit:

What test can you write that would fail unless T were a class?

You could write something like:

Type definition = typeof(MyClass<>);
Assert.Throws<ArgumentException>(() => definition.MakeGenericType(typeof(int)));

However, that seems to be going against the real purpose of testing...

like image 75
Jon Skeet Avatar answered Oct 11 '22 13:10

Jon Skeet