In a node.js application I have a class with a getter that contains a large switch statement, same as this but larger with unreleased-product-specific values instead of a, b, c, 1, 2, 3 etc:
Class SomeClass () {
constructor (someVar) {
this.someProp = someVar
}
get someGetter () {
switch (this.someProp) {
case 'a':
case 'b':
return 1
case 'c':
case 'd':
case 'e':
return 2
case 'f':
return 3
case undefined:
return null
default:
return 0
}
}
}
I then have a test case structured like this, that reaches each of the possible paths:
const expectedResults = new Map(Object.entries({
a: 1,
c: 2,
f: 3,
null: null,
z: 0
}))
for (const [testCase, expected] of expectedResults) {
const someInstance = new SomeClass(testCase)
t.equal(someInstance.someGetter, expected)
}
t.end()
This gave me coverage on all of the possible paths and no red flags in the node tap coverage report.
Hover, I get one (yellow) uncovered line, which is the line of the switch statement itself: line 6 in the example code, the line:
switch (this.someProp) {
I've tried adding redundant breaks after each return, but these are then (correctly!) flagged as uncovered (because they're unreachable).
I thought maybe it's complaining because it has a test for, for example, 'a' in the path that returns 1 but not 'b' in the same path. But if that's the problem I don't understand why it's flagging the switch statement itself, not those specific lines.
The uncovered line notice disappeared when I had the tests cover every possible case:, not just every path.
Since there were many, many cases in my real world code, and all of the return paths are tested as being correct, rather than extending the expectedResults map massively, I created another, simpler test condition which took a simple array of every case and simply made sure that each one was recognised (wasn't falling back to the default value). Like:
const allCases = ['a', 'b', 'c', 'd', 'e', 'f']
for (const testCase of allCases) {
const someInstance = new SomeClass(testCase)
t.notEqual(someInstance.someGetter, 0)
}
By comparing against the default fallback value, there's at least some value to this test, it's not purely there to meet 100% coverage: it makes sure no possible cases in the switch get deleted in future etc (e.g. if the switch statement is reordered or modified).
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