Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is conditional compilation a valid mock/stub strategy for unit testing?

In a recent question on stubbing, many answers suggested C# interfaces or delegates for implementing stubs, but one answer suggested using conditional compilation, retaining static binding in the production code. This answer was modded -2 at the time of reading, so at least 2 people really thought this was a wrong answer. Perhaps misuse of DEBUG was the reason, or perhaps use of fixed value instead of more extensive validation. But I can't help wondering:

Is the use of conditional compilation an inappropriate technique for implementing unit test stubs? Sometimes? Always?

Thanks.

Edit-add: I'd like to add an example as a though experiment:

class Foo {
    public Foo() { .. }
    private DateTime Now { 
      get {
#if UNITTEST_Foo
        return Stub_DateTime.Now;
#else
        return DateTime.Now;
#endif
      }
    }
    // .. rest of Foo members
}

comparing to

interface IDateTimeStrategy { 
    DateTime Now { get; }
}
class ProductionDateTimeStrategy : IDateTimeStrategy {
  public DateTime Now { get { return DateTime.Now; } }
}
class Foo {
    public Foo() : Foo(new ProductionDateTimeStrategy()) {}
    public Foo(IDateTimeStrategy s) { datetimeStrategy = s; .. }
    private IDateTime_Strategy datetimeStrategy;
    private DateTime Now { get { return datetimeStrategy.Now; } }
}

Which allows the outgoing dependency on "DateTime.Now" to be stubbed through a C# interface. However, we've now added a dynamic dispatch call where static would suffice, the object is larger even in the production version, and we've added a new failure path for Foo's constructor (allocation can fail).

Am I worrying about nothing here? Thanks for the feedback so far!

like image 384
Aaron Avatar asked Mar 01 '23 07:03

Aaron


2 Answers

Try to keep production code separate from test code. Maintain different folder hierarchies.. different solutions/projects.

Unless.. you're in the world of legacy C++ Code. Here anything goes.. if conditional blocks help you get some of the code testable and you see a benefit.. By all means do it. But try to not let it get messier than the initial state. Clearly comment and demarcate conditional blocks. Proceed with caution. It is a valid technique for getting legacy code under a test harness.

like image 98
Gishu Avatar answered May 12 '23 13:05

Gishu


I think it lessens the clarity for people reviewing the code. You shouldn't have to remember that there's a conditional tag around specific code to understand the context.

like image 30
plyawn Avatar answered May 12 '23 11:05

plyawn