18

I have just started using ScalaTest and I am using the following to compare two Doubles in my spec as follows:

  it should "calculate the price" in {
    val x = new X(10,10,12,1000)
    assert(x.price() === 185.92)
  }

The spec is passing even though I have put in a wrong value of 185.92 to compare against what the price function is returning (that actually returns 10.23 for the case above). I have other specs where I just compare Ints and they work as expected. But the ones involving Doubles are passing regardless. Is there another functions besides assert I should be using to compare Doubles?

EDIT:

def price () : Double
  • 1
    Not your actual question, but you shouldn't use `Double` (or any floating-point type) to represent a price. Use `BigDecimal` or a Spire type instead - a type that can perform exact decimal arithmetic anyway. – lmm Jan 07 '15 at 01:09
  • Yes, I will be using Spire but I'm just experimenting with ScalaTest at the moment. –  Jan 07 '15 at 01:43
  • My first theory is that x.price() is returning a type that thinks this instance is equal to Double 185.92. Can you show what type x.price() returns? Also, you can mix in org.scalactic.TypeCheckedEquality, or import org.scalactic.TypeCheckedEquality._ to get a type error if the types don't match up. – Bill Venners Jan 07 '15 at 01:49
  • @BillVenners, have added the definition for the `price` function. BTW, I can't fine TypeCheckedEquality. Has it been removed from scalatic? –  Jan 07 '15 at 02:05
  • Sorry, I didn't compile my comment! I meant TypeCheckedTripleEquals. Given that it looks like it is a Double, assuming you've not got a custom implicit Equality[Double] in scope that is extremely forgiving, it sounds more like your test may not be getting executed at all. Can you add more context? I.e., show the whole test class? If that is OK, I'd ask how you are executing the test and what the output looks like. – Bill Venners Jan 07 '15 at 02:10
  • 1
    Thanks Bill. ScalaTest is now highlighting the main issue. I mixed in the TypeCheckedTripleEquals and it showed up a type issue with a test just before the one in this post (in the same spec). The return type for the function in that test is `Double` but I was comparing it against an `Int` literal value. So it seems that ScalaTest ignored the tests after the one which had the type mismatch. –  Jan 07 '15 at 02:19

2 Answers2

25

It looks to me like you've got an implicit instance of Equality[Double] in scope along the lines of org.scalactic.TolerantNumerics, for which the documentation is here.

The example from the doc is:

implicit val doubleEquality = TolerantNumerics.tolerantDoubleEquality(0.01)

But it looks like somebody has instantiated it with a really big tolerance value in your case.

You may also consider trying explicit tolerance by using +-:

assert(x.price() === 185.92 +- 0.01)
Rodrigo López Dato
  • 1,144
  • 6
  • 13
Spiro Michaylov
  • 3,531
  • 21
  • 19
7

You can simply do actual shouldBe (expected +- tolerance) if using FlatSpec; other specs have similar matchers instead of shouldBe. It gives better messages in case of failures than assert, and the code is consistent with the other tests.

Abhijit Sarkar
  • 21,927
  • 20
  • 110
  • 219