Eagerly evaluated alternative to memoized.
The syntax of memoized values provide a short and concise way of storing values, and it is much nicer than using lateinit vars and a beforeEach blocks. However because it is lazily evaluated it can cause some strange issues, as shown in my previous issue (#645) and down below.
Today I encountered into another issues with a combination of mockito and spek's memoized. If you memoize a mock object A that stubs a function, and you memoize another mock B that stubs a function that returns mock A, mockito will fail because the memoized values are lazily evaluated and therefore mock A will be stubbed while B is being stubbed, which is not allowed by mockito. My solution to this problem was the same as with my previous issue; use lateinit vars and a beforeEach block.
The issue I just describe isn't very related to spek, however I still think spek should consider adding an alternative to memoized to make these things easier and cleaner than what we current have to do.
Related PR: #660
Can you add a small snippet of code? I think it will make things clearer to understand.
val a by memoized {
mock<Any>() {
// stub something
}
}
val b by memoized {
mock<Any>() {
// stub something that uses `a`
}
}
Because a and b are both memoized they aren't initialized until they are used. As b depends on a when its mock is created and being stubbed, a will also be created and stubbed while b is being stubbed. This behavior is disallowed by Mockito for some reason, and will throw an exception.
My issue isn't meant to be focused on this issue, but rather the suggestion of adding a new construct to spek for simplifying a common pattern, a pattern spek has already deemed common enough for adding the memoized function, thought I think the implementation of memoized hinders its usefulness.
One option is to add a lazy parameter to memoized, which defaults to true. I'll take a look at it more when I get back from vacation next week. Feel free to pull up a PR that explores that or any idea you might have.