
If possible, how do you fake the time for the purpose of triggering boost timers in a unit test?
A minimal example of achieving the requirements, based on a blog post by Chris (author of boost.asio) Thanks to the SO community for the providing hints. #include <boost/asio.hpp> #include <boost/optional.hpp> class mock_time_traits { typedef boost::asio::deadline_timer::traits_type source_traits; public: typedef source_traits::time_type time_type; typedef source_traits::duration_type duration_type; // Note this implemenation requires set_now(...) to be called before now() static time_type now() { return *now_; } // After modifying the clock, we need to sleep the thread to give the io_service // the opportunity to poll and notice the change in clock time static void set_now(time_type t) { now_ = t; boost::this_thread::sleep_for(boost::chrono::milliseconds(2)); } static time_type add(time_type t, duration_type d) { return source_traits::add(t, d); } static duration_type subtract(time_type t1, time_type t2) { return source_traits::subtract(t1, t2); } static bool less_than(time_type t1, time_type t2) { return source_traits::less_than(t1, t2); } // This function is called by asio to determine how often to check // if the timer is ready to fire. By manipulating this function, we // can make sure asio detects changes to now_ in a timely fashion. static boost::posix_time::time_duration to_posix_duration(duration_type d) { return d < boost::posix_time::milliseconds(1) ? d : boost::posix_time::milliseconds(1); } private: static boost::optional<time_type> now_; }; boost::optional<mock_time_traits::time_type> mock_time_traits::now_; typedef boost::asio::basic_deadline_timer< boost::posix_time::ptime, mock_time_traits> mock_deadline_timer; void handler(const boost::system::error_code &ec) { std::cout << "Handler!" << std::endl; } int main() { mock_time_traits::set_now(boost::posix_time::time_from_string("2013-01-20 1:44:01.000")); boost::asio::io_service io_service; mock_deadline_timer timer(io_service, boost::posix_time::seconds(5)); timer.async_wait(handler); std::cout << "Poll 1" << std::endl; io_service.poll(); mock_time_traits::set_now(mock_time_traits::now() + boost::posix_time::seconds(6)); std::cout << "Poll 2" << std::endl; io_service.poll(); std::cout << "Poll 3" << std::endl; io_service.poll(); return 0; } // Output Poll 1 Poll 2 Handler! Poll 3 The above is slightly modified (and I believe slightly improved) on the blog post. By not using an offset on the system clock, you gain complete control over the timers: they will not fire until you explicitly set time forward past the timer. The solution could be improved by making the this_thread::sleep part configurable. Note that the to_posix_duration hack described in [1] needs to use a smaller duration than the sleep. To me this approach still seems a bit magic, since the time_traits are not well documented, and in particular the hack of to_posix_duration has a whiff of voodoo about it. I guess it just comes down to intimate knowledge of the deadline_timer implementation (which I don't have).