swift - Unit-testing a functional core of value objects: how to verify contracts without mocking? -
i wanted give functional core/imperative shell approach shot, since swift's struct
s easy create.
now drive me nuts in unit tests.
how unit test net of value objects?
maybe i'm stupid search right terms, in end, more unit tests write, more think should delete old ones. in other words tests seem bubble call chain long don't provide mock objects. impossible (struct
) value objects, because there's no way replace them fake double unless introduce protocol, doesn't work in production code when methods return self
or have associated types.
here's simple example:
struct foo { func obtainbar() -> bar? { // ... } } struct foomanager { let foos: [foo] func obtainfirstbar() -> bar { // try `bar` every `foo` in `foos`; pass first // 1 isn't nil down } }
this works concrete foo
class or struct. how supposed test obtainfirstbar()
does? -- plug in 1 , 2 , 0 foo
instances , see happens.
but i'm replicating knowledge , assertions foo
's obtainbar()
. well, either move few footests
foomanagertests
, sounds stupid, or use mocks verify incoming call instead of merely asserting return value. can't subclass struct
, create protocol:
protocol footype { func obtainbar() -> bar } struct foo: footype { /* ... */ } class testfoo: footype { /* mocking/stubbing */}
when bar
complex enough warrant own unit tests , seems should mocked, end instead:
protocol footype { typealias b: bartype func obtainbar() -> b }
but compiler complain foomanager
's collection of foos
doesn't work way. thanks, generics.
struct foomanager<f: footype f.b == bar> { let foos: [f] // ^^^^^^^^^^^^^^^^ added clarity func obtainfirstbar() -> bar { /* ... */ } }
you can't pass in different kinds of foo
, though. 1 concrete footype
allowed, no weird mixes of bluefoo
, redfoo
, if both return same bar
, seem realize footype
protocol in same way. isn't objective-c , duck typing isn't possible. protocols don't seem add benefit in terms of abstraction here anyway unless they're not depending on else protocol or self.
if protocols lead confusion , not benefit @ all, i'd rather stop using them. how write unit tests if 1 object convoluted net of dependent objects, being value types, seldomly optional, without moving tests every permutation in test suite of root object(s)?
Comments
Post a Comment