Implement a secure parameterless constructor for unit testing

If I have a type with a large-old (many parameters) constructor, is it a valid approach for implementing a protected constructor without parameters just for the purpose of creating a derived type “fake” that will be used for capping in unit tests

An alternative is to extract the interface, but this is not always desirable in a code base on which you do not have full control over ...

+4
source share
4 answers

It is not perfect, but it is valid.

To quote a couple of people who know more about this than I do in The Art of Testing Units , Roy Osherove talks about unit tests as a user of code, and as such providing access specifically for them is not necessarily bad.

And Effectively working with legacy code , Michael Perce discusses several such methods, pointing out that creating test-protected things can be better than creating public ones, although this is not necessarily the best way to do something. (In fact, I would recommend that you read this book if you are working with legacy code, as it looks like you are).

I think it depends on what kind of code it is: if it is a public API in which people can get secure access so that it is overridden, this is probably a bad idea, but in a typical business application, where it is pretty obvious is not intended to be overridden, I do not think this is a problem. Sometimes I do this in this situation.

+2
source

Since you should essentially treat the protected as well as the public, the answer will not be from a strictly object-oriented point of view.

You could add a private constructor without parameters and at least call it through reflection if it is not too much trouble.

+2
source

Could you create a class that extends the class you want to test? This allows you to use your own constructor without having to create an interface.

Changing the code or API to facilitate unit testing is usually undesirable (see "Should I unit test private methods"), so actually using a new class, rather than changing an existing one, can be a way forward.

+1
source

There is an argument that non-print types should always declare a protected constructor without parameters (where your others have parameters).

This allows flexibility for subclasses to instantiate the class in their own way, rather than forcing parameters to be provided to the base constructor.

Mocking frameworks is just an example of a subclass that wants freedom to be able to instantiate the class in its own way; the mock object does not care about setting default values ​​or dependencies, since it will still mock return values.

One day, your own classes or library clients may have completely different ideas for setting up the class, and you don’t want the type that you can’t develop for several months to depend on what you are forced to push what is no longer you need to be in the ctor database.

There are rare cases when you absolutely must force to initialize the initialization value, but this is rare - note that structures should not have ctors without parameters.

0
source

All Articles