Skip to content

Instantly share code, notes, and snippets.

@aloiscochard
Created February 22, 2012 12:17
Show Gist options
  • Save aloiscochard/1884581 to your computer and use it in GitHub Desktop.
Save aloiscochard/1884581 to your computer and use it in GitHub Desktop.
Service mocking example using Sindi
package application
import sindi._
import service.a._
import service.x.module._
object AppContext extends Context {
override lazy val modules = new ServiceXModule :: Nil
// ServiceA1/2 could be defined in a common module, or independent module ...
// to simplify the example I just use them directly in the application context.
// It would be easier to mock if you have a ready to use module containing all your different services,
// e.g this AppContext could be changed to a module.
override val bindings = Bindings(
bind[ServiceA1] to
new ComponentContext with ServiceA1 with ServiceXComponent,
bind[ServiceA2] to
new ComponentContext with ServiceA2 with ServiceXComponent,
// Let's mock dat shit in a single line!
bind[service.x.ServiceX] to new service.x.ServiceX { def f(x: String): Unit = println("mocked: " + x) }
)
val serviceA1 = inject[ServiceA1]
val serviceA2 = inject[ServiceA2]
serviceA1.f("hello")
serviceA2.f("hello")
}
// EXECUTION RESULT
//scala> application.AppContext
//mocked: hello
//mocked: hello
//res0: application.AppContext.type = application.AppContext$@4be85a3d
package service.a
// We depend on ServiceXProvider instead of ServiceXComponent,
// to avoid polluting the core application with IoC dependecy
// this is totally optional, and was not the main objective of this example ;)
// Otherwise we should "import sindi._" here ...
trait ServiceA1 extends service.x.ServiceXProvider {
def f(x: String): Unit = serviceX.f(x)
}
// You can use self type annotation to avoid having multiple feature provider conflicting with each others.
trait ServiceA2 { self: service.x.ServiceXProvider =>
def f(x: String): Unit = self.serviceX.f(x)
}
package service.x
package object module {
import sindi._
final class ServiceXModule(implicit context: Context) extends Module {
override val bindings: Bindings =
bind[ServiceX] to new ServiceXDefault
def service = inject[ServiceX] // This boilerplate will be optional in future version!
}
trait ServiceXComponent extends Component with ServiceXProvider {
def serviceX = from[ServiceXModule].service
}
}
trait ServiceX {
def f(x: String): Unit
}
class ServiceXDefault extends ServiceX {
def f(x: String): Unit = println(x)
}
// Using a 'provider' is optional, but it make possible for ServieAs to not have dependencies on Sindi.Component
trait ServiceXProvider {
def serviceX: ServiceX
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment