The use of the trait in Q / A that you referenced really dealt with the flexibility provided by blending traits.
In the example, when you explicitly decrypt a trait, the compiler blocks the types of the class and superclass at compile time. In this example, MyService is LockingFlavorA
trait Locking { // ... } class LockingFlavorA extends Locking { //... } class MyService extends LockingFlavorA { }
When you used typed self-determination (as shown in Q / A that you pointed to):
class MyService { this: Locking => }
.. Locking can refer to Locking itself or to any valid Locking subclass. Then the author mixes up in the implementation of blocking on the call site without creating a new class for this purpose:
val myService: MyService = new MyService with JDK15Locking
I think when they say that you can make testing easier, they really talk about using this function to mimic what we Java developers usually do with compositions and mock objects. You simply execute the Locking layout and mix it during the test and do the real implementation for the runtime.
To your question: is this better or worse than using a mock library and dependency injection? It would be difficult to say, but I think that in the end many of them will go on how well one method or another plays with the rest of your code base.
If you are already successfully applying composition and addiction, I would consider continuation of this model to be a good idea.
If you are just starting out and really do not need all this artillery, or if you have not philosophically decided that dependency injection is right for you, you can get many miles from mixins for a very low cost in execution complexity.
I think that the true answer will be very situational.
TL DR lower
Question 1) I think this is a situationally useful alternative to / dep -inj, but I do not think that it provides any significant gain, except perhaps for simplicity.
Question 2) Yes, this can improve testability, mainly by emulating simulated objects through the implementation of features.