Pregunta

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?

¿Fue útil?

Solución

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))
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top