Unit testing non-public types and members for .NET projects

Unit testing is usually used for testing public types and members. However, there are cases when you might need to test types or members that are not public. These could be internal classes or private helper methods, for instance. Whether that is proper unit testing or beyond its scope is not a discussion that I want to get into here. However, in this post, I will show how you can unit test non-public types and members from .NET assemblies.

When faced with the need for testing non-public types and members you can use several approaches:

  • change the accessibility to public; you can do that perhaps only for debug builds and keep the intended accessibility in release builds by using conditional compilation.
  • provide public members of a class that invoke private ones;
  • use reflection.

The first solutions involve changing the API only for the sake of the testing. The last solution avoids that but requires more work. To help with that, the Visual Studio unit testing framework provides some helper types that enable you to focus on the actual testing and be less concerned about the reflection details.

When a type is not a type

Class template argument deduction is a useful feature in C++17 that helps developers to simplify the code by avoiding writing the template argument list when initializing objects of class templates (or when performing function-style casts). The compiler provides an implicit set of deduction guides, which are fictional function templates for a hypothetical class and uses them to perform template argument deduction and overload resolution. However, you can extend this set of deduction guides with your own, and in some cases, such as for aggregate types, you need to do so.

croncpp – a C++ library for CRON expressions

A CRON expression is a string composed of six fields (in some implementation seven), separated by a whites space, representing a time schedule. CRON expressions are used in various job schedulers (such as the Linux job scheduler, the Quartz scheduler, Azure scheduler for functions, etc.). Recently, I have written a C++ library for parsing such expressions and determining the next occurrence of the scheduled time. The library is called croncpp. It is written in C++17, is header-only, open-source and cross-platform, and can be found on GitHub.

C++ rules for special member functions

C++ has several special member functions that are defined by the compiler even if not defined by the user. These special member functions are the default constructor, the copy constructor, the copy assignment operator, the move constructor, the move assignment operator, and the destructor. However, there are many rules for what is defined and in which circumstances. For instance, if no special member function is defined by the user then all of them are implicitly defined by the compiler. On the other hand, if a copy constructor or copy assignment operator is defined by the user, then the move constructor and move assignment operator are not defined by the compiler. To make it easier to comprehend all the rules, the following table describes what is defined by the compiler based on what is defined by the user.

Partial function applications

Partial function application is the process of taking a function with a number of arguments, fixing (or binding) some of its arguments and producing a new function with a smaller number of arguments. In C++, this can be achieved with std::bind() that generates a forwarding call wrapper for a callable object, and the placeholder objects from the std::placeholders namespace that are used for binding arguments to the callable object.

C++17 removed and deprecated features

Along with the new features added to the language and the standard library in C++17, there are also existing features that have been either removed (after being deprecated in a previous version) or deprecated so they would be removed sometime in the future. Although not complete, the following tables list the most important of these removed or deprecated features.