Question

I have some components with mixed traits which contains system logic (caching, services etc). And need to mock this logic in tests. It's simple...

But also i need to test bundles of components with same cache and i cannot share some global cache. So, my solution is:

In code:

trait Component
class MyComponent1 extends Component with Cache with Services { ... }
class MyComponent2 extends Component with Cache with Services { ... }
trait Cache {
   private val _cache = ...
   def query(...) = ...
}

In test API:

trait CacheMock extends Cache {
   private[package] var _cache = null //to be injected
   override def query(...) = _cache.get(...)
}

case class Config(cacheMock: Cache)

trait TestAPI {
    val componentCreator: => List[Component] 

    def test(config: Config) = {
       val instances = componentCreator
       instances foreach {
           case mocked: CacheMock => mocked._cache = config.cacheMock
           case _ =>
       } 
       instances 
    }
}

In tests:

class Test extends TestAPI {
    def componentCreator = List(new MyComponent1 with CacheMock, new MyComponent2 with CacheMock)

    test(Config(mock1))
    test(Config(mock2))
}

The alternative solution is to use parametrized factory in componentCreator: Cache => List[Component], but it's a little ugly.

So is there any better solution, which can also provide a simple DSL (without boilerplate), but without var assigning? Or framework which can solve same problems?

Was it helpful?

Solution

Doesn't compile just like your code, but it should explain my idea:

class TestMyComponent1(protected _cache: Cache) extends MyComponent1 with CacheMock
class TestMyComponent2(protected _cache: Cache) extends MyComponent2 with CacheMock

trait CacheMock extends Cache {
   protected val _cache: Cache
   override def query(...) = _cache.get(...)
}

class Test extends TestAPI {
  def componentCreator = List(new TestMyComponent1(mock1), new TestMyComponent2(mock2))
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top