title: Conditional Derivation for Unit Testing
body: <p>I'm writing unit tests that encapsulate a hardware driver (user space), the design pattern that I'm using is as follows:</p>
  
  <pre><code>class uio
  {
      virtual uint32_t readbit(...);
      virtual bool writebit(...);
      // other driver related functions
      // ...
  };
  
  class uio_test : public uio
  {
      virtual uint32_t readbit(...) override { /* don't talk to hardware, send back test data */ }
      virtual bool writebit(...) override { /* don't talk to hardware, write test data */ }
  };
  
  class spi : public uio
  {
      // spi related functions
  };
  
  class i2c : public uio
  {
      // i2c related functions
  };
  </code></pre>
  
  <p>My questions is how to go about making spi and uio properly inherit from either uio OR uio_test depending on the module (real program vs gtest). I've looked at conditionals for example:</p>
  
  <pre><code>template&lt;bool test&gt;
  class spi : public std::conditional&lt;test, uio_test, uio&gt;
  </code></pre>
  
  <p>and this would work in world where all objects were derived simply from the main.</p>
  
  <pre><code>/* main.cpp */
  spi&lt;false&gt; s;
  s.init();
  s.writebit();
  
  /* gtest_main.cpp */
  spi&lt;true&gt; s;
  ASSERT_TRUE(s.init());
  ASSERT_EQ(/* read/write test bits, etc*/);
  </code></pre>
  
  <p>however the uio derived objects are used in other specialized classes throughout the program, and I cannot see a good way of conditional construction, for example:</p>
  
  <pre><code>class temperature_monitor
  {
      createBuses();
      spi&lt;???&gt;* spictrl_;
  };
  
  /* perhaps derive test classes, easy since most high level objects are singletons */
  temperature_monitor::createBuses()
  {
      if (testmode)
          spictrl_ = new spi&lt;true&gt;;
      else
          spictrl_ = new spi&lt;false&gt;;     
  }
  </code></pre>
  
  <p>Hope that's clear as mud for everyone. I'll answer a few questions before they're asked:</p>
  
  <p>Q. How about pre-processor conditionals?</p>
  
  <p>A. No, if possible, never.</p>
  
  <p>Q. Why are you writing unit tests for low level bit banging drivers like spi?</p>
  
  <p>A. Why not, there's some internal logic going on, and I'd rather catch errors in a unit test than try and debug a stupid missing 0 for a day.</p>