Scala Mixin特质成员冲突问题及解决方案咨询
解决方案
推荐方案:重构CPODBTestContainerSpec移除冲突的Spec风格
问题根源是CPODBTestContainerSpec继承了AnyFlatSpecLike,而PlaySpec本身继承了AnyWordSpecLike,两者定义了大量同名方法导致冲突。最干净的解决方式是让CPODBTestContainerSpec只负责测试容器的生命周期管理,不绑定特定的ScalaTest风格:
- 修改
CPODBTestContainerSpec的定义,去掉AnyFlatSpecLike:
trait CPODBTestContainerSpec extends TestContainerForAll { // 保留原有的测试容器初始化、配置逻辑 .... }
- 保持
BaseCPOControllerSpec的继承结构不变:
abstract class BaseCPOControllerSpec extends PlaySpec with Results with FakeApplicationFactory with CPODBTestContainerSpec { .... }
这样BaseCPOControllerSpec只会使用PlaySpec的AnyWordSpecLike风格,同时获得TestContainerForAll的测试容器能力,完全消除方法冲突。
备选方案:在BaseCPOControllerSpec中显式覆盖冲突方法
如果无法修改CPODBTestContainerSpec(比如它被其他使用AnyFlatSpecLike的测试类依赖),可以在BaseCPOControllerSpec中显式覆盖所有冲突方法,指定使用PlaySpec的实现:
import org.scalatest._ abstract class BaseCPOControllerSpec extends PlaySpec with Results with FakeApplicationFactory with CPODBTestContainerSpec { // 覆盖所有冲突方法,委托给PlaySpec的实现 override protected def info: Informer = super[PlaySpec].info override protected def note: Informer = super[PlaySpec].note override protected def alert: Informer = super[PlaySpec].alert override protected def markup: MarkupInformer = super[PlaySpec].markup override protected def registerTest(testName: String, testTags: Tag*)(testFun: => Unit): Unit = super[PlaySpec].registerTest(testName, testTags:_*)(testFun) override protected def registerIgnoredTest(testName: String, testTags: Tag*)(testFun: => Unit): Unit = super[PlaySpec].registerIgnoredTest(testName, testTags:_*)(testFun) override lazy val it: ResultOfItWord = super[PlaySpec].it override lazy val they: ResultOfTheyWord = super[PlaySpec].they override lazy val behave: BehaveWord = super[PlaySpec].behave override val styleName: String = super[PlaySpec].styleName }
这种方式通过显式指定父类实现解决冲突,但需要维护所有冲突方法的覆盖代码,后续如果ScalaTest新增相关方法可能需要再次更新。
内容的提问来源于stack exchange,提问作者joesan
相关产品推荐
相关产品推荐

