Reputation: 1110
Sometimes you just have a list of operations that need to be performed in a set order, like when implementing a sequence diagram. What are the best ways to enforce code execution order, to prevent refactoring introducing subtle bugs through a change of sequence?
Let's assume that existing unit tests would not catch any problems caused by changing the order of the execution of foo() and bar() in the following.
A few of the methods I've seen and used:
Comments (relies on people reading & understanding them):
// do this
foo();
// then this
bar();
Fluent grammar (to make the code read more like English and discourage wanton refactoring):
obj
.Do
.foo()
.Then
.bar();
State variables & balking (too elaborate):
foo_done=false;
if(foo()) foo_done=true;
if(foo_done) bar(); else throw_an_exception;
Grouping logical blocks into functions:
void foo_bar()
{
foo();
bar();
}
...and many more too ugly to describe (nesting, events, arrays of function pointers, naming functions Begin(), Middle() and End()...).
Are there any better-engineered patterns for doing this sort of thing?
Upvotes: 0
Views: 308
Reputation: 472
You write unit tests to check what happened (state, attributes change) after you call a procedure, so I don't think you need to check if some method was called or not.
Also, if you tie your test to some method, later on, if you change your system to use another method with the same effects of foo(), your test will fail even when your system is doing the right things.
Upvotes: 0
Reputation: 4174
I'm confused as to why the order is significant if unit tests wouldn't catch them, and the dependencies aren't explicit in the code; it implies that side effects are a crucial part of the operation of foo() and bar(). In the which case, the best design strategy would be to make these side-effects explicit!
Upvotes: 1