I ran into a failing C# unit test today, with the following output:
But was: True
Seriously. I stopped it in the debugger and the property that was being checked was “true”. I set it to a local and that was also “true” in the debugger.
So when is it the case that true != true?
The answer, to me, was straight forward: in C#, “true” is supposed to be the 32-bit value 0x00000001, but in many languages, “true” is defined as “anything that is not ‘false’ (aka, 0).
Since the code that was generating the value was C++/CLI interfacing with C, it seemed pretty clear where the issue was – I opened up a Memory window in the debugger and dropped the member onto it, which showed that the value for the boolean was 0x00002080 (or something like that). The culprit was C++ code that was calling a low-level C function, passing in two locals by reference. The receiving C code had recently been (incompletely) changed to reflect a change in a separate API which formerly set those values, but was obsoleted. The C++ assumed that the C would set them as an OUT parameter (as it had), but was now instead leaving them with whatever had been on the stack at the time.
Lesson 1 – when you refactor code to no longer set OUT parameters, remove those parameters and see where the errors trickle up.
Lesson 2 – don’t assume that OUT parameters are set in C/C++ – initialize your locals.
Lesson 3 – just because the debugger says it’s true, doesn’t mean that it is or, one person’s true is another person’s false.
These problems would not have turned up if NUnit’s Assert.IsTrue wasn’t implemented as Assert.AreEqual(true, b, message) which brings up another coding issue – you should avoid comparing against true and false as constants (this is idiomatic in C), but in this case it caught a bug.
About the AuthorFollow on Twitter More Content by Steve Hawley