You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First of all, thank you all for the awesome Scala FP DI Framework. We use it a lot.
Today, I have one question regarding the best way of implementing global bootstrap logic to be run before all tests.
Currently, we do it like this
// Some base class for all testsclassBaseZioItSpecextendsSpec3[ZIO]
with ... {
overridedefconfig:TestConfig=TestConfig(
pluginConfig =PluginConfig.const(DefaultPlugin),
moduleOverrides =newModuleDef {
...
make[Unit].named("global-start").fromEffect(fixtureBootstrap _)
},
forcedRoots =Set(
...
DIKey.get[Unit].named("global-start")
),
memoizationRoots =Set(
...
DIKey.get[Unit].named("global-start"),
)
)
...
/** Creates test data */deffixtureBootstrap(
xa: Transactor[Task],
someRepository: SomeRepository,
userService: UserService
):UIO[Unit] = {
for {
_ <-UIO(println("Bootstrapping data for tests"))
_ <- userService.createUser(NewUser("test-1"...))
...
} yield ()
}
}
The problem:
Although we have our fixtureBootstrap run once before all tests, we have a problem with the userService and its dependencies. The arguments of fixtureBootstrap and ALL nested dependencies (there could be quite a lot of them) of the components in the arguments are created only once and shared across all tests.
This is undesirable sometimes.
We potentially can only inject Transactor[Task] into fixtureBootstrap only and duplicate some logic from other components like userService to "unblock it" and make it re-creatable on every test, but there may be another way of doing it.
Please kindly advise how we can define a global bootstrap logic without pinning some portion of the instances in the DI graph.
Thank you.
The text was updated successfully, but these errors were encountered:
We potentially can only inject Transactor[Task] into fixtureBootstrap only and duplicate some logic from other components like userService to "unblock it" and make it re-creatable on every test, but there may be another way of doing it.
This is what we do in general.
Alternatively you can make named copies of the graphs that you use in the startup task. Though that may be bothersome to do - you'll need to assign names to all the components AND to their dependencies - to prevent dependencies from being memoized:
valconstructorOfUserService=AnyConstructor[UserService]
valconstructorOfSomeRepository=AnyConstructor[SomeRepository]
defmakeAllDependenciesNamed[A](functoid: Functoid[A], name: Identifier):Functoid[A] = {
valnewProvider= functoid.get.replaceKeys {
caseDIKey.TypeKey(tpe, m) =>DIKey.IdKey(paramTpe, name.id, m)(name.idContract)
case k => k
}
Functoid(newProvider)
}
valglobalModule=newModuleDef {
make[UserService].named("global").from(makeAllDependenciesNamed(constructorOfUserService, "global"))
make[SomeRepository].named("global").from(makeAllDependenciesNamed(constructorOfSomeRepository, "global"))
... make[SomeRepositoryDep].named("global").from(...) ...
}
There could be a better solution for this in the future with private bindings
Thank you for the details and provided snippet @neko-kai!
I'll give it a try with makeAllDependenciesNamed, and will wait for the private bindings to be available in future releases.
Hi, Team!
First of all, thank you all for the awesome Scala FP DI Framework. We use it a lot.
Today, I have one question regarding the best way of implementing global bootstrap logic to be run before all tests.
Currently, we do it like this
The problem:
Although we have our
fixtureBootstrap
run once before all tests, we have a problem with theuserService
and its dependencies. The arguments offixtureBootstrap
and ALL nested dependencies (there could be quite a lot of them) of the components in the arguments are created only once and shared across all tests.This is undesirable sometimes.
We potentially can only inject
Transactor[Task]
intofixtureBootstrap
only and duplicate some logic from other components likeuserService
to "unblock it" and make it re-creatable on every test, but there may be another way of doing it.Please kindly advise how we can define a global bootstrap logic without pinning some portion of the instances in the DI graph.
Thank you.
The text was updated successfully, but these errors were encountered: