Polymerase
Polymerase

Reputation: 6801

ScalaTest how to exclude MustMatchers if multiple Matchers are mixed in

Using Scalatest 2.2.5, Scala 2.11.8, sbt 0.13.13, JDK 1.8.121

Our code base evolves and developers have different preferences regarding the testing style and matchers. In the code below, the test uses Matchers, it also needs to mixin a trait OurCommonTestHelpers which ifself mixes in MustMatchers in its declaration. It is easy to solve, just remove with Matchers and replace should equal with must equal. Let's pretend that I like better the verb should, just for the sake that because it is used in the ScalaTest User Guide

We would probably standardize one day. But for now, is it possible to exclude a matcher in case of conflict?

import org.scalatest.{FreeSpec, Matchers}

class MyBizLogicTest extends FreeSpec 
with Matchers // <-- conflict with MustMatchers from trait OurCommonTestHelpers  
with OurCommonTestHelpers 
{
  "A trivial addition" in {
      (1 + 2) should equal (3)
  }
}

trait OurCommonTestHelpers extends MockitoSugar with MustMatchers {
  ???
} 

The code failed compilation:

Error:(26, 7) class MyBizLogicTest inherits conflicting members:
  method convertSymbolToHavePropertyMatcherGenerator in trait Matchers of type (symbol: Symbol)MyBizLogicTest.this.HavePropertyMatcherGenerator  and
  method convertSymbolToHavePropertyMatcherGenerator in trait MustMatchers of type (symbol: Symbol)MyBizLogicTest.this.HavePropertyMatcherGenerator
(Note: this can be resolved by declaring an override in class MyBizLogicTest.);
 other members with override errors are: equal, key, value, a, an, theSameInstanceAs, regex, <, >, <=, >=, definedAt, evaluating, produce, oneOf, atLeastOneOf, noneOf, theSameElementsAs, theSameElementsInOrderAs, only, inOrderOnly, allOf, inOrder, atMostOneOf, thrownBy, message, all, atLeast, every, exactly, no, between, atMost, the, convertToRegexWrapper, of
class MyBizLogicTest extends FreeSpec

NOTE: I have tried to exclude the MustMatchers by import org.scalatest.{MustMatchers => _} but this has no effect on the compile error.

Upvotes: 1

Views: 469

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170745

I don't think you can, given that neither class inherits another. The obvious approach would be to add an extra type:

// name just to be clear, I don't suggest actually using this one
trait OurCommonTestHelpersWithoutMatchers extends ... {
  // everything in OurCommonTestHelpers which doesn't depend on MustMatchers
}

trait OurCommonTestHelpers extends OurCommonTestHelpersWithoutMatchers with MustMatchers {
  ...
}

class MyBizLogicTest extends FreeSpec 
with Matchers 
with OurCommonTestHelpersWithoutMatchers 
{
  "A trivial addition" in {
      (1 + 2) should equal (3)
  }
}

NOTE: I have tried to exclude the MustMatchers by import org.scalatest.{MustMatchers => _} but this has no effect on the compile error.

You can't remove inherited members by not importing them. If you accessed them by importing in OurCommonTestHelpers, you would simply not import them in MyBizLogicTest (but would need to import in other classes where you need them).

Upvotes: 1

Related Questions