Suppose you have function which takes a union type and then narrows the type and delegate to one of two other pure functions.
function foo(arg: string|number) {
if (typeof arg === 'string') {
return fnForString(arg)
} else {
return fnForNumber(arg)
}
}
Assume that fnForString()
and fnForNumber()
are also pure functions, and they have already themselves been tested.
How should one go about testing foo()
?
fnForString()
and fnForNumber()
as an implementation detail, and essentially duplicate the tests for each of them when writing the tests for foo()
? Is this repetition acceptable?foo()
delegate to fnForString()
and fnForNumber()
e.g. by mocking them out and checking that it delegates to them?A pure function is a function where the return value is only determined by its input values, without observable side effects. When a function performs any other “action”, apart from calculating its return value, the function is impure. Single impure function would contaminate any function that calls it.
A function must pass two tests to be considered “pure”: Same inputs always return same outputs. No side-effects.
The only result of calling a pure function is the return value. Examples of pure functions are strlen(), pow(), sqrt() etc. Examples of impure functions are printf(), rand(), time(), etc.
The best solution would be just testing for foo
.
fnForString
and fnForNumber
are an implementation detail that you may change in the future without necessarily changing the behaviour of foo
.
If that happens your tests may break with no reason, this kind of problem makes your test too expansive and useless.
Your interface just needs foo
, just test for it.
If you have to test for fnForString
and fnForNumber
keep this kind of test apart from your public interface tests.
This is my interpretation of the following principle stated by Kent Beck
Programmer tests should be sensitive to behaviour changes and insensitive to structure changes. If the program’s behavior is stable from an observer’s perspective, no tests should change.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With