In test code occasionally I want to set/mock some global variables and at the end of test/scope I want to restore these variables. For example:
BOOST_AUTO_TEST_CASE(HttpClientCsrf)
{
std::string csrfSave = Http::getCsrfToken();
... some test code
Http::setCsrfToken(csrfSave); // restore csrf
}
Obvious problem here is that if some test code
returns (or throws) before reaching the end you won't restore that csrfSave
variable. So, simple improvement is to write some simple struct wrapper that restores the value automatically in dtor:
struct CsrfSave
{
std::string csrfSave;
CsrfSave()
{
csrfSave = Http::getCsrfToken();
}
~CsrfSave()
{
Http::setCsrfToken(csrfSave);
}
};
BOOST_AUTO_TEST_CASE(HttpClientCsrf)
{
CsrfSave csrfSave;
... some test code
// dtor of CsrfSave restores csrf
}
This solves the problem in general, however, for each function you'd need to write lots of boilerplate code. So, the question is: what are shortest and simplest approaches could be used to achieve the same, while minimizing and possibly avoiding all that boilerplate.
One such approach that I use, and I'm not too happy about it:
BOOST_AUTO_TEST_CASE(HttpClientCsrf)
{
std::string csrfSave = RBX::Http::getLastCsrfToken();
shared_ptr<void> csrfSaveScope(NULL, [&](void*) {
RBX::Http::setLastCsrfToken(csrfSave);
});
... some test code
}
Is there anything better? I'd prefer to avoid writing any utility classes and would prefer to avoid boost (unless it's something that's included in next std). This kind of pattern happens quite often in different projects (that do not share code) and each time I end up writing either simple struct wrapper or generic wrapper that takes lambda and I would like to see other approaches that can be coded in-place just like I showed in my shared_ptr exmpale