Advertisement
Guest User

Unit Test C++ With Platform Dependency

a guest
Jan 29th, 2014
547
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.35 KB | None | 0 0
  1.     // ConsoleApplication2.cpp : Defines the entry point for the console application.
  2.     //
  3.  
  4.     #include "stdafx.h"
  5.     #include <thread>
  6.     #include <chrono>
  7.     #include <memory>
  8.     #include <assert.h>
  9.  
  10.     bool must_sleep()
  11.     {
  12.         return true;
  13.     }
  14.  
  15.     class untestable_class
  16.     {
  17.     public:
  18.  
  19.         void some_function()
  20.         {
  21.             if (must_sleep())
  22.             {
  23.                 auto sleep_duration = std::chrono::milliseconds(1000);
  24.                 std::this_thread::sleep_for(sleep_duration);
  25.             }
  26.         }
  27.     };
  28.  
  29.     void use_untestable_class()
  30.     {
  31.         untestable_class instance;
  32.         instance.some_function();
  33.     }
  34.  
  35.     struct system_thread_policy1
  36.     {
  37.         static void sleep_milliseconds(long milliseconds)
  38.         {
  39.             auto sleep_duration = std::chrono::milliseconds(milliseconds);
  40.             std::this_thread::sleep_for(sleep_duration);
  41.         }
  42.     };
  43.  
  44.     struct mock_thread_policy1
  45.     {
  46.         // Mock attributes to verify interactions.
  47.         static size_t sleep_milliseconds_count;
  48.         static size_t sleep_milliseconds_arg1;
  49.  
  50.         // Resets the mock attributes before usage.
  51.         static void sleep_milliseconds_reset()
  52.         {
  53.             sleep_milliseconds_count = 0;
  54.             sleep_milliseconds_arg1 = 0;
  55.         }
  56.  
  57.         static void sleep_milliseconds(size_t milliseconds)
  58.         {
  59.             sleep_milliseconds_count++;
  60.             sleep_milliseconds_arg1 = milliseconds;
  61.         }
  62.     };
  63.  
  64.     // This is needed with MS compilers to keep all mock code in a header file.
  65.     __declspec(selectany) size_t mock_thread_policy1::sleep_milliseconds_count;
  66.     __declspec(selectany) size_t mock_thread_policy1::sleep_milliseconds_arg1;
  67.  
  68.     template <typename thread_policy>
  69.     class testable_class1
  70.     {
  71.     public:
  72.  
  73.         void some_function()
  74.         {
  75.             if (must_sleep())
  76.             {
  77.                 thread_policy::sleep_milliseconds(sleep_duration_milliseconds);
  78.             }
  79.         }
  80.  
  81.     private:
  82.  
  83.         enum { sleep_duration_milliseconds = 1000 };
  84.     };
  85.  
  86.     void use_testable_class1()
  87.     {
  88.         testable_class1<system_thread_policy1> instance;
  89.         instance.some_function();
  90.     }
  91.  
  92.     void test_testable_class1()
  93.     {
  94.         mock_thread_policy1::sleep_milliseconds_reset();
  95.         testable_class1<mock_thread_policy1> instance;
  96.         instance.some_function();
  97.  
  98.         assert(mock_thread_policy1::sleep_milliseconds_count == 1);
  99.         assert(mock_thread_policy1::sleep_milliseconds_arg1 == 1000);
  100.         //assert("some observable behavior on instance");
  101.     }
  102.  
  103.     struct system_thread_policy2
  104.     {
  105.         void sleep_milliseconds(size_t milliseconds) const
  106.         {
  107.             auto sleep_duration = std::chrono::milliseconds(milliseconds);
  108.             std::this_thread::sleep_for(sleep_duration);
  109.         }
  110.     };
  111.  
  112.     struct mock_thread_policy2
  113.     {
  114.         mutable size_t sleep_milliseconds_count;
  115.         mutable size_t sleep_milliseconds_arg1;
  116.  
  117.         mock_thread_policy2()
  118.             : sleep_milliseconds_count(0)
  119.             , sleep_milliseconds_arg1(0)
  120.         {
  121.         }
  122.  
  123.         void sleep_milliseconds(size_t milliseconds) const
  124.         {
  125.             sleep_milliseconds_count++;
  126.             sleep_milliseconds_arg1 = milliseconds;
  127.         }
  128.     };
  129.  
  130.     template <typename thread_policy>
  131.     class testable_class2
  132.     {
  133.     public:
  134.  
  135.         testable_class2(const thread_policy& policy = thread_policy()) : m_thread_policy(policy) { }
  136.  
  137.         void some_function() const
  138.         {
  139.             if (must_sleep())
  140.             {
  141.                 m_thread_policy.sleep_milliseconds(sleep_duration_milliseconds);
  142.             }
  143.         }
  144.  
  145.     private:
  146.  
  147.         // Needed since the thread policy is taken as a reference.
  148.         testable_class2(const testable_class2&);
  149.         testable_class2& operator=(const testable_class2&);
  150.  
  151.         enum { sleep_duration_milliseconds = 1000 };
  152.  
  153.         const thread_policy& m_thread_policy;
  154.     };
  155.  
  156.     void use_testable_class2()
  157.     {
  158.         const testable_class2<system_thread_policy2> instance;
  159.         instance.some_function();
  160.     }
  161.  
  162.     void test_testable_class2()
  163.     {
  164.         mock_thread_policy2 thread_policy;
  165.         const testable_class2<mock_thread_policy2> instance(thread_policy);
  166.         instance.some_function();
  167.  
  168.         assert(thread_policy.sleep_milliseconds_count == 1);
  169.         assert(thread_policy.sleep_milliseconds_arg1 == 1000);
  170.         //assert("some observable behavior on instance");
  171.     }
  172.  
  173.     class testable_class3
  174.     {
  175.     public:
  176.  
  177.         void some_function()
  178.         {
  179.             if (must_sleep())
  180.             {
  181.                 sleep_milliseconds(sleep_duration_milliseconds);
  182.             }
  183.         }
  184.  
  185.     private:
  186.  
  187.         virtual void sleep_milliseconds(size_t milliseconds)
  188.         {
  189.             auto sleep_duration = std::chrono::milliseconds(milliseconds);
  190.             std::this_thread::sleep_for(sleep_duration);
  191.         }
  192.  
  193.         enum { sleep_duration_milliseconds = 1000 };
  194.     };
  195.  
  196.     class mock_testable_class3 : public testable_class3
  197.     {
  198.     public:
  199.  
  200.         size_t sleep_milliseconds_count;
  201.         size_t sleep_milliseconds_arg1;
  202.  
  203.         mock_testable_class3()
  204.             : sleep_milliseconds_count(0)
  205.             , sleep_milliseconds_arg1(0)
  206.         {
  207.         }
  208.  
  209.     private:
  210.  
  211.         virtual void sleep_milliseconds(size_t milliseconds)
  212.         {
  213.             sleep_milliseconds_count++;
  214.             sleep_milliseconds_arg1 = milliseconds;
  215.         }
  216.     };
  217.  
  218.     void use_testable_class3()
  219.     {
  220.         // Lots of opportunities to optimize away the virtual dispatch.
  221.         testable_class3 instance;
  222.         instance.some_function();
  223.     }
  224.  
  225.     void test_testable_class3()
  226.     {
  227.         mock_testable_class3 mock_instance;
  228.         auto test_function = [](testable_class3& instance) { instance.some_function(); };
  229.         test_function(mock_instance);
  230.  
  231.         assert(mock_instance.sleep_milliseconds_count == 1);
  232.         assert(mock_instance.sleep_milliseconds_arg1 == 1000);
  233.         //assert("some observable behavior on mock_instance");
  234.     }
  235.  
  236.     int _tmain(int argc, _TCHAR* argv[])
  237.     {
  238.         test_testable_class1();
  239.         test_testable_class2();
  240.         test_testable_class3();
  241.  
  242.         return 0;
  243.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement