unittest questions

Steven Schveighoffer schveiguy at yahoo.com
Mon Aug 23 06:07:32 PDT 2010


On Thu, 19 Aug 2010 14:08:33 -0400, Johannes Pfau <spam at example.com> wrote:

> Hi, I wrote some unittests using the built-in d unittest and a came
> across 2 problems:
>
> 1) I have some code that accepts both delegates and functions. How can a
> unittest explicitly check the function part? Whenever I add a function
> in an unittest block it becomes a delegate.
> ---------------------------------------------------
> void add(T)(T handler) if (is(T == void function())){}
> void add(T)(T handler) if (is(T == void delegate())){}
>
> unittest
> {
>     //always a delegate
>     void handler() {};
>     add(&handler);
> }
> ----------------------------------------------------

I know others have answered this, but to aid in your understanding of  
*why* it works this way, a unittest block is actually a function itself.   
So declaring a function inside it is like declaring a nested function.

In essence, the compiler lumps together all of your unit test blocks into  
one function per module, and stores a pointer to that function in a  
ModuleInfo object.  Then the runtime calls all of these functions on  
startup.

>
> 2) I know Errors should not be caught. But when I expect a function to
> throw in debug mode, but not necessarily in release mode (assert), I
> have to check for both Errors and Exceptions --> Throwable. Is it OK to
> catch Throwables in this case?
> ----------------------------------------------------
> unittest
> {
>     void handler() {};
>     bool thrown = false;
>     try
>         add(&handler);
>     catch(Throwable)
>         thrown = true;
>
>     assert(thrown);
> }
> ----------------------------------------------------
>

I'd say that the appropriate thing to do here is to catch the exceptions  
you would expect to be thrown  i.e.:

unittest
{
     void handler() {};
     bool thrown = false;
     try
         add(&handler);
     catch(DerivedFromException)
         thrown = true;
     catch(DerivedFromError)
         thrown = true;

     assert(thrown);
}

ideally, you should be able to predict which exception gets thrown so you  
only have one catch statement.  The point of unit tests are to ensure  
behavior is within specifications.  If your specification is that a  
function can throw anything, then I think the specification needs work.

-Steve


More information about the Digitalmars-d-learn mailing list