This question is about dealing with testing of classes which mix in non-interface traits, that is traits containing some functionality. When testing, the class functionality
How about:
val helpers = new HttpHelpers {
//override or define stuff the trait needs to work properly here
}
helpers.someMethodToTest
Look, Ma, no intermediate traits and mocking libraries needed!
I do that all the time for my traits and I've been pretty happy with the result.
You can write an Helper mock trait which should be mixed with HttpHelpers
and override its methods with mock equivalent:
trait HttpHelpersMock { this: HttpHelpers =>
//MOCK IMPLEMENTATION
override protected def withResponse[A](resp: HttpResponse)(fun: HttpResponse => A): A = // ...
//MOCK IMPLEMENTATION
override protected def makeGetRequest(url: String): HttpResponse = // ...
}
Then, when testing crawler, you mix the mock trait at instantiation:
val crawlerTestee = new Crawler(x) with HttpHelpersMock
And the mock methods will just replace the helper methods in instance crawlerTestee
.
Edit: I don't think its a good idea to test how a class interacts with an helper trait. In my opinion, you should test Crawler
behavior and not its internal implementation detail. Implementations can change but the behavior should stay as stable as possible. The process I described above allows you to override helper methods to make them deterministic and avoid real networking, thus helping and speeding tests.
However, I believe it make sense to test the Helper itself, since it may be reused elsewhere and has a proper behavior.