Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // ConsoleApplication2.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #include <thread>
- #include <chrono>
- #include <memory>
- #include <assert.h>
- bool must_sleep()
- {
- return true;
- }
- class untestable_class
- {
- public:
- void some_function()
- {
- if (must_sleep())
- {
- auto sleep_duration = std::chrono::milliseconds(1000);
- std::this_thread::sleep_for(sleep_duration);
- }
- }
- };
- void use_untestable_class()
- {
- untestable_class instance;
- instance.some_function();
- }
- struct system_thread_policy1
- {
- static void sleep_milliseconds(long milliseconds)
- {
- auto sleep_duration = std::chrono::milliseconds(milliseconds);
- std::this_thread::sleep_for(sleep_duration);
- }
- };
- struct mock_thread_policy1
- {
- // Mock attributes to verify interactions.
- static size_t sleep_milliseconds_count;
- static size_t sleep_milliseconds_arg1;
- // Resets the mock attributes before usage.
- static void sleep_milliseconds_reset()
- {
- sleep_milliseconds_count = 0;
- sleep_milliseconds_arg1 = 0;
- }
- static void sleep_milliseconds(size_t milliseconds)
- {
- sleep_milliseconds_count++;
- sleep_milliseconds_arg1 = milliseconds;
- }
- };
- // This is needed with MS compilers to keep all mock code in a header file.
- __declspec(selectany) size_t mock_thread_policy1::sleep_milliseconds_count;
- __declspec(selectany) size_t mock_thread_policy1::sleep_milliseconds_arg1;
- template <typename thread_policy>
- class testable_class1
- {
- public:
- void some_function()
- {
- if (must_sleep())
- {
- thread_policy::sleep_milliseconds(sleep_duration_milliseconds);
- }
- }
- private:
- enum { sleep_duration_milliseconds = 1000 };
- };
- void use_testable_class1()
- {
- testable_class1<system_thread_policy1> instance;
- instance.some_function();
- }
- void test_testable_class1()
- {
- mock_thread_policy1::sleep_milliseconds_reset();
- testable_class1<mock_thread_policy1> instance;
- instance.some_function();
- assert(mock_thread_policy1::sleep_milliseconds_count == 1);
- assert(mock_thread_policy1::sleep_milliseconds_arg1 == 1000);
- //assert("some observable behavior on instance");
- }
- struct system_thread_policy2
- {
- void sleep_milliseconds(size_t milliseconds) const
- {
- auto sleep_duration = std::chrono::milliseconds(milliseconds);
- std::this_thread::sleep_for(sleep_duration);
- }
- };
- struct mock_thread_policy2
- {
- mutable size_t sleep_milliseconds_count;
- mutable size_t sleep_milliseconds_arg1;
- mock_thread_policy2()
- : sleep_milliseconds_count(0)
- , sleep_milliseconds_arg1(0)
- {
- }
- void sleep_milliseconds(size_t milliseconds) const
- {
- sleep_milliseconds_count++;
- sleep_milliseconds_arg1 = milliseconds;
- }
- };
- template <typename thread_policy>
- class testable_class2
- {
- public:
- testable_class2(const thread_policy& policy = thread_policy()) : m_thread_policy(policy) { }
- void some_function() const
- {
- if (must_sleep())
- {
- m_thread_policy.sleep_milliseconds(sleep_duration_milliseconds);
- }
- }
- private:
- // Needed since the thread policy is taken as a reference.
- testable_class2(const testable_class2&);
- testable_class2& operator=(const testable_class2&);
- enum { sleep_duration_milliseconds = 1000 };
- const thread_policy& m_thread_policy;
- };
- void use_testable_class2()
- {
- const testable_class2<system_thread_policy2> instance;
- instance.some_function();
- }
- void test_testable_class2()
- {
- mock_thread_policy2 thread_policy;
- const testable_class2<mock_thread_policy2> instance(thread_policy);
- instance.some_function();
- assert(thread_policy.sleep_milliseconds_count == 1);
- assert(thread_policy.sleep_milliseconds_arg1 == 1000);
- //assert("some observable behavior on instance");
- }
- class testable_class3
- {
- public:
- void some_function()
- {
- if (must_sleep())
- {
- sleep_milliseconds(sleep_duration_milliseconds);
- }
- }
- private:
- virtual void sleep_milliseconds(size_t milliseconds)
- {
- auto sleep_duration = std::chrono::milliseconds(milliseconds);
- std::this_thread::sleep_for(sleep_duration);
- }
- enum { sleep_duration_milliseconds = 1000 };
- };
- class mock_testable_class3 : public testable_class3
- {
- public:
- size_t sleep_milliseconds_count;
- size_t sleep_milliseconds_arg1;
- mock_testable_class3()
- : sleep_milliseconds_count(0)
- , sleep_milliseconds_arg1(0)
- {
- }
- private:
- virtual void sleep_milliseconds(size_t milliseconds)
- {
- sleep_milliseconds_count++;
- sleep_milliseconds_arg1 = milliseconds;
- }
- };
- void use_testable_class3()
- {
- // Lots of opportunities to optimize away the virtual dispatch.
- testable_class3 instance;
- instance.some_function();
- }
- void test_testable_class3()
- {
- mock_testable_class3 mock_instance;
- auto test_function = [](testable_class3& instance) { instance.some_function(); };
- test_function(mock_instance);
- assert(mock_instance.sleep_milliseconds_count == 1);
- assert(mock_instance.sleep_milliseconds_arg1 == 1000);
- //assert("some observable behavior on mock_instance");
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- test_testable_class1();
- test_testable_class2();
- test_testable_class3();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement