has anyone heard of a library that provides a dele...
# announcements
z
has anyone heard of a library that provides a delegated property for constructing things in JUnit’s setUp phase automatically? instead of:
Copy code
private lateinit var dog: Dog

@Before fun setUp() {
  dog = Dog()
}
there would be:
Copy code
private val dog by before { Dog() } // constructs `Dog` instance once per test
seems like this could be pretty useful?
w
You’d need to hook into test lifecycle somehow. It’s what rules are for, so such delegated property would still need to have @Rule annotation and would have to implement a Rule, I think
s
Why not just
Copy code
class MyDogTest {
    private val dog = Dog()
    ...
    @Test fun someTest() { .... dog .... }
    ...
}
? Most (if not all) unit-test-runners I know always create a brand new instance of
MyDogTest
for every unit-test function that is executed.
👆 3
p
I also removed all my @Before functions which made my tests way clearer because now there are no lateinits any longer
w
Yep, I don’t know why I thought rule is even useful if you’re not closing the object 🤦‍♂️ In JUnit afaik there’s no difference between creating an instance inline vs @Before method: https://stackoverflow.com/a/6094143/1349855
v
A common use case for @before and instantiation that I run into is when I need to substitute my coroutine dispatcher with the test version in the
android.Viewmodel
and there is something in the init {} block that runs the coroutine or observes the flow.
w
if a property is written before an
init
block, it’s initialized first
v
Yes, but in
coroutines-test
it's the `Dispatchers::setMain`invocation that is required to set the main dispatcher... But I guess it could also be injected
w
Oh you meant the other way around! Technically in that case you can also have an
init
block before the property declaration (and another init block later if you want)
👍 1
s
Yup; we usually inject it. There is a
setMain
, but no such hooks such as
setDefault
or
setIO
🙂
(or use @Inject with Dagger 🙂 )
m
By default, JUnit Jupiter and JUnit4 create a new instance of the test for each method execution, therefore the
val dog = Dog()
is acceptable. BUT some frameworks, including JUnit Jupiter allow for a change to that lifecycle so the test is only instantiated ONCE, and all test methods are then run. https://junit.org/junit5/docs/current/user-guide/#writing-tests-test-instance-lifecycle
👍 1