6 ms·
Great article. The only thing I would add is that anything other than `assertEquals(expectedValue, actualValue)` is not really permissible. Don't make assertion
by bvanderveen 6y ago
Great article. The only thing I would add is that anything other than `assertEquals(expectedValue, actualValue)` is not really permissible. Don't make assertions about 'portion' or 'subset' of your results, make assertions about the entire value! Otherwise, you're throwing away an opportunity to encode a constraint; sooner or later the undefined behavior will make itself known. We are writing tests to avoid that scenario in the first place, no?
- joshka 6y agoPartial Disagreement on the phrasing of this - there are many classes of assertion like `assertThat(expected).containsInAnyOrder(foo,bar,baz);` that would not meet this. Order often does not matter and cannot be constrained. There are other things similar to this.
- bvanderveen 6y agoValue should probably be a `Set` then!
- sk5t 6y agoThere are ordered sets, immutable sets... infinite sequences, lazy lists, sometimes collections are hairy to test.
- bvanderveen 6y agoIf find that if I am trying to test values that are not 'fully realizable' (infinite, lazy, etc) there's typically a temporal aspect involved, and I have a 'mock clock and timer' implementation so that I can call a `time.advance(t)` from within my tests and time advances in my system under test. This works because (as OP also noted) I only use my own mockable abstractions for answering the question 'what time is it?' and for instructing the system 'call me back at time t'. The net effect being I can fully define the behavior of the system within an arbitrary window of time—and collect the resulting values or behavior into some data structure which encodes what happened and when, and then compare it against expected results. Re immutable: the values you're getting from your system under test and the expected values you're constructing in tests should always be immutable!
- dodobirdlord 6y agoWhat if it's a repeated field of a protocol buffer? Parse it into a set and then check it? That's exactly what `assertThat(expected).containsInAnyOrder(foo,bar,baz);` is doing anyway.
- bvanderveen 6y agoI'm not very familiar with protobuf, but in searching, repeated field seems to have list- or set-like semantics, so yeah, I'd parse the value into a list or a set and compare it to a list or a set.
- dodobirdlord 6y agoIf you were going to work with protocol buffers frequently you'd probably quickly find yourself doing this over and over, and would then create the aforementioned `assertThat(expected).containsInAnyOrder(foo,bar,baz);`.
- twic 6y agoYou might have separate assertions or separate tests for the different aspects. Insisting on only asserting equality forces you to lump them together, which can make the failure less clear.
- bvanderveen 6y agoHonest question, what kind of data type can't be compared to another instance of itself for equality? I have never encountered a situation where I have a value of a type which has some 'aspect' that cannot all be incorporated into the definition of `equals()` for its type. Seems to contravene the very notion of values and types. What am I missing?