RefSpec allows you to define tests as methods, which saves one function literal per test compared to style classes that represent tests as functions. Fewer function literals translates into faster compile times and fewer generated class files, which can help minimize build times. As a result, using Spec can be a good choice in large projects where build times are a concern as well as when generating large numbers of tests programatically via static code generators. import org.scalatest._ import refspec._ class SetSpec extends RefSpec { override def withFixture(test: NoArgTest) = { // Define a shared fixture // Shared setup (run at beginning of each test) try test() finally { // Shared cleanup (run at end of each test) } } // Describe a scope for a subject, in this case: "A Set" object `A Set` { // All tests within these curly braces are about "A Set" // Can describe nested scopes that "narrow" its outer scopes object `(when empty)` { // All tests within these curly braces are about "A Set (when empty)" def `should have size 0` = { // Here, 'it' refers to "A Set (when empty)". The full name assert(Set.empty.size == 0) // of this test is: "A Set (when empty) should have size 0" } def `should produce NoSuchElementException when head is invoked` = { // Define another test intercept[NoSuchElementException] { Set.empty.head } } @Ignore def `should should be empty` = { // To ignore a test, change 'it' to 'ignore'... assert(Set.empty.isEmpty) } } // Describe a second nested scope that narrows "A Set" in a different way object `(when non-empty)` { // All tests within these curly braces are about "A Set (when non-empty)" def `should have the correct size` = { // Here, 'it' refers to "A Set (when non-empty)". This test's full assert(Set(1, 2, 3).size == 3) // name is: "A Set (when non-empty) should have the correct size" } // Define a pending test by using { pending } for the body def `return a contained value when head is invoked` = { pending } import org.scalatest.tags.Slow @Slow def `should be non-empty` = { // Tag a test by placing a tag object after the test name assert(Set(1, 2, 3).nonEmpty) } } } } @DoNotDiscover // Disable discovery of a test class class InvisibleSpec extends RefSpec { /*code omitted*/ } @Ignore // Ignore all tests in a test class class IgnoredSpec extends RefSpec { /*code omitted*/ } import tags.Slow @Slow // Mark all tests in a test class with a tag class SlowSpec extends RefSpec { /*code omitted*/ } |
|||||
Note: The remainder of this page is identical no matter which style trait you use. | |||||
Assertions | |||||
---|---|---|---|---|---|
import org.scalatest._ import Assertions._ val (a, b, c, d) = (1, 2, 3, 4) assert(a == b || c >= d) // Error message: 1 did not equal 2, and 3 was not greater than or equal to 4 assertResult(2) { c + d } // Error message: Expected 2, but got 7 intercept[IllegalArgumentException] { // Error message: Expected exception java.lang.IllegalArgumentException c / 0 // to be thrown, but java.lang.ArithmeticException was thrown. } fail("I've got a bad feeling about this") // Error message: I've got a bad feeling about this // Succeeds if doesn't compile because of type or syntax error assertDoesNotCompile("val a: Int = 1") // Error message: Expected a compiler error, but got none for code: // val a: Int = 1 // Succeeds only if a type error assertTypeError("val a: Int = 1") // Error message: Expected a type error, but got none for code: // val a: Int = 1 // Succeeds only if no type or syntax error assertCompiles("_") // Error message: Expected no compiler error, but got the following parse error: // "unbound placeholder parameter", for code: _ // Tests that can't run because of missing preconditions should be canceled cancel("Network was down") // Error message: Network was down // Tests can also be canceled with assume case class Database(available: Boolean) val db = Database(false) assume(db.available) // Error message: db.available was false // You can add clues to error messages assert(a == b, ", but you already knew that") // Error message: 1 did not equal 2, but you already knew that assertResult(2, ", what a bummer!") { a + b } // Error message: Expected 2, but got 3, what a bummer! assume(db.available, "yet again") // Error message: db.available was false yet again withClue("prepended clue") { // Error message: prepended clue 1 did not equal 2 assert(a == b) } import AppendedClues._ assert(a == b) withClue "appended clue" // Error message: 1 did not equal 2 appended clue | |||||
Matchers - Equality and identity | |||||
import org.scalatest.Matchers._ def incr(i: Int) = i + 1 val result = incr(2) result should equal (3) // By default, calls left | |||||
Matchers - Object's class | |||||
import org.scalatest.Matchers._ class Tiger val tiger = new Tiger tiger shouldBe a [Tiger] // Ensure an object is an instance of a specified class or trait val tigerList = List(tiger) // Because type parameters are erased on the JVM, you must use tigerList shouldBe a [List[_]] // an underscore for any type parameters when using this syntax |
|||||
Matchers - Expected exceptions | |||||
import org.scalatest.Matchers._ val s = "hai" an [IndexOutOfBoundsException] should be thrownBy { // Ensure a particular exception type is thrown s.charAt(-1) } val caught = the [IndexOutOfBoundsException] thrownBy { // Capturing an expected exception in a variable s.charAt(-1) } the [IndexOutOfBoundsException] thrownBy { // Inspecting an expected exception s.charAt(-1) } should have message ("String index out of range: -1") |
|||||
Matchers - Length and size | |||||
import org.scalatest.Matchers._ val result = "hai" result should have length 3 // Works for any type T for which an implicit Length[T] is available, including String, // Array, scala.collection.GenSeq, java.util.List, and any object with length field or // method or getLength method; the length value can be Int or Long. result should have size 3 // Works for any type T for which an implicit Size[T] is available, including String, Array, // scala.collection.GenTraversable, java.util.Collection, java.util.Map, and any object with // size field or method or getSize method; the size value can be Int or Long. |
|||||
Matchers - Strings and regular expressions | |||||
import org.scalatest.Matchers._ val string = "Hello World" string should startWith ("Hello") // starts with the given substring string should endWith ("world") // ends with the given substring string should include ("seven") // includes the given substring string should startWith regex "Hel*o" // starts with a substring matching the regular expression string should startWith regex "Hel*o".r // (works with String or Regex) string should endWith regex "wo.ld".r // ends with a substring matching the regular expression string should include regex "wo.ld".r // includes substring matching regular expression val re = """(-)?(\d+)(\.\d*)?""".r string should fullyMatch regex re // includes substring matching regular expression | |||||
Matchers - Order and ranges | |||||
import org.scalatest.Matchers._ val one = 1 one should be < 7 // works for any T when an implicit Ordered[T] exists one should be <= 7 one should be >= 0 val num = 8 num should (be >= 1 and be <= 10) // one way to ensure a value is within a range or tolerance. val seven = 7 seven should be (6 +- 2) // another way to verify a range 7.0 should be (6.9 +- 0.2) // works for both integral and floating point types |
|||||
Matchers - Checking boolean properties with be |
|||||
import org.scalatest.Matchers._ // access a boolean property dynamically (via reflection) Set(1, 2, 3) should be ('nonEmpty) // will also match isNonEmpty import java.io.File val temp = new File("aFile.txt") temp should be a ('file) // can use an optional 'a' or 'an' import java.awt._ import event.KeyEvent val canvas = new Canvas val keyEvent = new KeyEvent(canvas, 0, 0, 0, 0, '0') keyEvent should be an ('actionKey) import org.scalatest._ class FileBePropertyMatcher extends // For static checking, a BePropertyMatcher can be defined. BePropertyMatcher[java.io.File] { def apply(left: File) = BePropertyMatchResult(left.isFile, "file") } val file = new FileBePropertyMatcher val temp = new File("aFile.txt") temp should be a file |
|||||
Matchers - Using arbitrary be matchers |
|||||
import org.scalatest._ // To place an arbitrary token after
|
|||||
Matchers - Checking arbitrary properties with have |
|||||
import org.scalatest.Matchers._ case class Book(title: String, author: String, pubYear: Int) val book = Book("A Book", "Sally", 2008) book should have ( // check arbitrary properties dynamically (via reflection) 'title ("A Book"), // see HavePropertyMatcherGenerator 'author ("Sally"), 'pubYear (2008) ) import org.scalatest._ // check arbitrary properties statically with HavePropertyMatchers import Matchers._ import matchers._ case class Book(title: String, author: String) def title(expectedValue: String) = new HavePropertyMatcher[Book, String] { def apply(book: Book) = HavePropertyMatchResult( book.title == expectedValue, "title", expectedValue, book.title ) } def author(expectedValue: String) = new HavePropertyMatcher[Book, String] { def apply(book: Book) = HavePropertyMatchResult( book.author == expectedValue, "author", expectedValue, book.author ) } val book = Book("A Book", "Sally") book should have ( title ("A Book"), author ("Sally") ) |
|||||
Matchers - Working with Scala and Java collections | |||||
import org.scalatest.Matchers._ List.empty[Int] should be (empty) // various ways of checking whether a collection is empty List.empty[Int] should be (Nil) Map.empty[Int, String] should be (Map()) Set.empty[Int] should be (Set.empty) Set(1, 2, 3) should have size (3) // check the size of a collection Set(1, 2, 3) should have size (3) List(1, 2, 3) should have length (3) Set("three", "five", "seven") should contain ("five") // check whether a traversable contains an element val map = Map(1 -> "one", 2 -> "two", 3 -> "three") map should contain key (1) // check whether a map contains a particular key or value should contain value ("two") import PartialFunctionValues._ // check both that a map is defined at a key as Map("I" -> 1, "II" -> 2, "III" -> 3).valueAt("II") should equal (2) // well as something about its value import java.util._ val javaCol = new ArrayList[Int] javaCol should be (empty) // Check if a java.util.Collection is empty val javaMap = new java.util.HashMap[Int, String] javaMap.put(1, "one") javaMap.put(2, "two") javaMap.put(3, "three") javaMap should have size (3) // check the size of a java.util.Map val javaList = new ArrayList[Int] javaList.add(1) javaList.add(2) javaList.add(3) javaList should have length (3) // check the length of a java.util.List val javaCol = new HashSet[String] javaCol.add("three") javaCol.add("five") javaCol.add("seven") // Check whether a java.util.Collection contains a javaCol should contain ("five") // particular element val javaMap = new HashMap[Int, String] javaMap.put(1, "one") javaMap.put(2, "two") javaMap.put(3, "three") javaMap should contain key (1) // Check whether a java.util.Map contains a particular key val javaMap = new HashMap[Int, String] javaMap.put(1, "Hi") javaMap.put(2, "Howdy") javaMap.put(3, "Hai") javaMap should contain value ("Howdy") // Check whether a java.util.Map contains a particular value |
|||||
Matchers - Working with Option and Either |
|||||
import org.scalatest.Matchers._ val option = Some(1) option should be (Some(1)) // Check whether an Option contains a certain value val option = Some(1) option shouldBe defined // Check whether an Option is defined val option = Some(1) option shouldBe empty // Check whether an Option is empty val option = None option should be (None) // Another way to check whether an Option is empty val either = Left(1) either should be ('left) // Check whether an Either is a Left val either = Left(1) either should be (Left(1)) // Check whether an Either is Left with a certain value val either = Right(1) either should be ('right) // Check whether an Either is a Right val either = Right(1) either should be (Right(1)) // Check whether an Either is Right with a certain value import org.scalatest.EitherValues._ val either = Right(3) // Check both that an Either is defined as well as something either.right.value should be < 7 // about its value |
|||||
Checking for emptiness | |||||
import org.scalatest.Matchers._ List.empty shouldBe empty // Check if a List (and any GenTraversable) is empty None shouldBe empty // Check if an Option is empty "" shouldBe empty // Check if a String is empty new java.util.HashMap[Int, Int] shouldBe empty // Check if a java.util.Map is empty new { def isEmpty = true } shouldBe empty // Check if a structural type is empty Array.empty shouldBe empty // Check if an Array is empty |
|||||
Matchers - Working with "containers" |
|||||
import org.scalatest.Matchers._
List(1, 2, 3) should contain (2) // Check if a List (or any GenTraversable) contains the
// specified element
Map('a' -> 1, 'b' -> 2, 'c' -> 3) should contain ('b' -> 2) // Check if a Map contains the specified mapping
Set(1, 2, 3) should contain (2) // Check if various collections contain a specified element
Array(1, 2, 3) should contain (2)
"123" should contain ('2')
Some(2) should contain (2)
import org.scalactic.Explicitly._ // Using
|
|||||
Matchers - Working with "aggregations" |
|||||
import org.scalatest.Matchers._
List(1, 2, 3) should contain atLeastOneOf (2, 3, 4) // Check if a List (or any GenTraversable) contains at least one of
// the specified elements
Array(1, 2, 3) should contain atLeastOneOf (3, 4, 5) // Check if an Array contains at least one of the specified
// elements
"abc" should contain atLeastOneOf ('c', 'a', 't') // Check if a String contains at least one of the specified
// characters
import org.scalactic.Explicitly._ // Using
|
|||||
Matchers - Working with "sequences" |
|||||
import org.scalatest.Matchers._ // Check if a List (or any GenTraversable) List(1, 2, 2, 3, 3, 3) should contain inOrderOnly (1, 2, 3) // contains only the specified elements in same // order Array(1, 2, 2, 3, 3, 3) should contain inOrderOnly (1, 2, 3) // Check if an Array contains only the specified // elements in same order "122333" should contain inOrderOnly ('1', '2', '3') // Check if a String contains only the specified // characters in same order List(0, 1, 2, 2, 99, 3, 3, 3, 5) should contain inOrder (1, 2, 3) // Check if a List (or any GenTraversable) // contains the specified elements in same order List(1, 2, 3) should contain theSameElementsInOrderAs Vector(1, 2, 3) // Check if a List (or any GenTraversable) // contains the same elements in same order as the // specified Vector (or any GenTraversable) | |||||
Matchers - Working with iterators |
|||||
import org.scalatest.Matchers._// Use toStream to convert Iterator to Stream to work with contain val it = List(1, 2, 3).iterator it.toStream should contain (2) | |||||
Matchers - Working with File |
|||||
import org.scalatest.Matchers._ import java.io.File val javaHomeDir = new File(System.getProperty("java.home")) javaHomeDir should exist // Check if a directory exists val javaHomeLicenseFile = javaHomeDir + System.getProperty("file.separator") + "LICENSE") javaHomeLicenseFile should exist // Check if a file exists javaHomeLicenseFile shouldBe readable // Check if a file is readable javaHomeLicenseFile shouldBe writable // Check if a file is writable | |||||
Matchers - Inspector Shorthands | |||||
import org.scalatest.Matchers._ val xs = List(1, 2, 3, 4, 5) all (xs) should be < 10 // check that all elements in xs are less than 10 atMost (2, xs) should be >= 4 // check that at most 2 elements in xs are greater than or // equal to 4 atLeast (3, xs) should be < 5 // check that at least 3 elements in xs are lesser than 5 between (2, 3, xs) should (be > 1 and be < 5) // check that 2 to 3 elements in xs are greater than 5 and less // than 5 exactly (2, xs) should be <= 2 // check that 2 elements in xs are less than or equal to 2 every (xs) should be < 10 // check that all elements in xs are less than 10 |
|||||
Matchers - Logical expressions with and , or , and not |
|||||
import org.scalatest.Matchers._ val result = 8 result should (be > 0 and be < 10) // You can and matcher expressions together val map = Map("hi" -> "HI", "hei" -> "HEI", "he" -> "HE") map should (contain key ("hi") or contain key ("ho")) // You can or matcher expressions together val result = "Hello Word" // You can negate a matcher expression result should not be (null) val map = Map("one" -> 1, "two" -> 2, "three" -> 3) map should (contain key ("two") and not contain value (7)) // Another example of negation |
|||||
Matchers - When you need a different matcher | |||||
import org.scalatest.Matchers._
import java.awt._
import event.KeyEvent
val canvas = new Canvas // You can check boolean properties dynamically with be and
val keyEvent = new KeyEvent(canvas, 0, 0, 0, 0, '0') // a Symbol (the tick mark syntax). For statically typed
keyEvent should be an ('actionKey) // approach, use a BePropertyMatcher or BeMatcher.
case class Book(title: String, author: String) // You can check arbitrary properties dynamically with have
val book = Book("A Tale of Two Cities", "Sally") // and a Symbol (the tick mark syntax). For a statically
book should have ('title("A Tale of Two Cities")) // typed approach, use a HavePropertyMatchers.
val defined = 'defined // One way to get rid of the tick mark for a dynamic
Some("hi") should be (defined) // property check
val beDefined = be ('defined) // One way to get rid of the tick mark and a pair of
Some("hi") should beDefined // parentheses
val beWithinTolerance = be >= 0 and be <= 10 // You can combine matchers with and, or, and not
8 should beWithinTolerance
import matchers._ // You can compose a matcher with a function that
val beOdd = Matcher((i: Int) => // transforms the input type
MatchResult(
i % 2 != 0,
i + " is not odd",
i + " is odd"))
val beOddAsInt = beOdd compose { (s: String) => s.toInt }
"3" should beOddAsInt
import java.io.File // You can also use matcher composition to create a new
def endWithExtension(ext: String) = // matcher given a parameter
endWith(ext) compose { (f: File) => f.getPath }
new File("output.txt") should endWithExtension("txt")
val beOdd = Matcher { (left: Int) => // You can use a factory method to define a custom matcher
MatchResult( // (such factory methods also exist for
|
|||||
Selenium DSL | |||||
import org.scalatest._ import selenium._ class BlogSpec extends Spec with WebBrowser with HtmlUnit { val host = "http://localhost:9000/" def `The blog app home page should have the correct title` { go to (host + "index.html") pageTitle should be ("Awesome Blog") } } go to "http://www.scalatest.org" // Go to ScalaTest website pageTitle should be ("ScalaTest") // Check page title click on "q" // Click on element which has attribute id or name = "q" click on id("q") // Click on element which has attribute id = "q" click on name("name") // Click on element which has attribute name = "q" click on tagName("input") // Click on element which is an 'input' tag click on className("quickref") // Click on element which has the CSS class 'quickref' tag cssSelector("a[id='aLink']").element.tagName should be ("a") // Check a element's tag name, selected by using CSS // selector linkText("Click Me!").element.tagName should be ("a") // Check a element's tag name, selected by using the link // text partialLinkText("Click").element.tagName should be ("a") // Check a element's tag name, selected by using the // partial link text enter("Cheese!") // Enter "Cheese!" into currently selected text element submit() // Submit form textField("q").value = "Cheese!" // Set text field (which has attribute id or name = "q") // to "Cheese!" textField("q").value should be ("Cheese!") // Read and check a text field (which has attribute id or // name = "q") value radioButtonGroup("group1").value = "Option 2" // Set radio button group (which has group name = "group1") // or // to choose "Option 2" radioButtonGroup("group1").selection = Some("Option 2") radioButtonGroup("group1").value should be ("Option 2") // Read and check radio button group (which has group // or // name = "group1") chosen value radioButtonGroup("group1").selection should be (Some("Option 2")) click on radioButton("opt1") // Click on a radio button (which has attribute id or // name = "opt1") radioButton("opt1").isSelected should be (true) // Check if a radio button (which has attribute id or // name = "opt1") is selected checkbox("cbx1").select() // Select a check box (which has attribute id or name = // "cbx1") checkbox("cbx1").clear() // Clear a check box (which has attribute id or name = // "cbx1") checkbox("cbx1").isSelected should be (true) // Check if a check box (which has attribute id or name = // "cbx1") is selected singleSel("select1").value = "option2" // Set a single-selection dropdown list (which has // or // attribute id or name = "select1") to choose "option2" singleSel("select1").selection = Some("option2") singleSel("select1").clear() // Clear the selection of a single-selection dropdown list // or // (which has attribute id or name = "select1") singleSel("select1").selection = None singleSel("select1").value should be ("option2") // Read and check currently selected value of a // or // single-selection dropdown list (which has attribute id singleSel("select1").selection should be (Some("option2")) // or name = "select1") multiSel("select2").values = Seq("option5", "option6") // Set the selection of a multi-selection list (which has // attribute id or name = "select2") multiSel("select2").values += "option3" // Select "option3" in addition to current selection of a // multi-selection list (which has attribute id or name = // "select2") multiSel("select2").clear("option5") // Clear "option5" from current selection of a // multi-selection list (which has attribute id or name = // "select2") multiSel("select2").clearAll() // Clear all selection of a multi-selection list (which // has attribute id or name = "select2") multiSel("select2").values should have size 2 // Read and check currently selected values of a multiSel("select2").values(0) should be ("option5") // multi-selection list (which has attribute id or name = multiSel("select2").values(1) should be ("option6") // "select2") goBack() // Go back to previous page in history goForward() // Go forward to next page in history reloadPage() // Reload the current page add cookie ("name1", "value1") // Add new cookie with name = "name1" and value = "value1" cookie("name1").value should be ("value1") // Read and check a cookie's value delete cookie "name1" // Delete cookie "name1 delete all cookies // Delete all cookies under the same domain. capture to "MyScreenShot" // Capture the screen and save as "MyScreenShot.png" setCaptureDir("/home/your_name/screenshots") // Set the directory to save captured pictures. withScreenshot { // Auto capture screen when something goes wrong (e.g. assert("Gold" == "Silver", "Expected gold, but got silver") // test failed) } close() // Close current browser window quit() // Close all windows and exit the driver |
|||||
Concurrent Support | |||||
import org.scalatest._ // eventually retries the block until it import concurrent.Eventually._ // no longer throws an exception, using a import Matchers._ // timeout and interval taken from an // implicit PatienceConfig. The default // PatienceConfig is 150 milliseconds // timeout and 15 milliseconds interval. // If you import IntegrationPatience, // you'll get a 15 second timeout and 150 // milliseconds interval. If you want // something else, you can define your own // implicit PatienceConfig like the next // example. val it = Vector("sad", "happy").iterator eventually { it.next shouldBe "happy" } import org.scalatest.time.SpanSugar._ // Define custom implicit PatienceConfig implicit val patienceConfig = PatienceConfig(timeout = scaled(2 seconds), interval = scaled(5 millis)) import org.scalatest.time._ // Use eventually with explicit timeout eventually (timeout(Span(5, Seconds))) { /*code omitted*/ } eventually (timeout(5 seconds), interval(5 millis)) { /*code omitted*/ } // Use eventually with explicit timeout // and interval |
|||||
Inspectors | |||||
import org.scalatest._ import Matchers._ import Inspectors._ forAll(List(1, 2, 3)) { _ should be > 0 } // Check that every element passes the assertion block forAtLeast(1, List(1, 2, 3)) { _ should be > 2 } // Check that at least the specified number of elements // pass the assertion block forAtMost(2, List(1, 2, 3)) { _ should be > 1 } // Check that at most the specified number of elements pass // the assertion block forBetween(2, 4, List(1, 2, 3, 4, 5)) { _ should be > 2 } // Check that the specified minimum and maximum number of // elements (inclusive) pass the assertion block forEvery(List(1, 2, 3)) { _ should be > 0 } // Check that every element passes the assertion block, // listing all failing elements on failure (whereas forAll // just reports the first failing element) forExactly(2, List(1, 2, 3)) { _ should be > 1 } // Check that the exact specified number of elements pass // the assertion block | |||||
Single-element collections | |||||
import org.scalatest._ // Use | |||||
Inside | |||||
import org.scalatest._ import Matchers._ import Inside._ // Checking nested object graph using Inside case class Name(first: String, middle: String, last: String) case class Record(name: Name, age: Int) val rec = Record( Name("Sally", "Anna", "Jones"), 38 ) inside (rec) { case Record(name, age) => inside (name) { case Name(first, middle, last) => first should be ("Sally") } } | |||||
OptionValues | |||||
import org.scalatest._ import OptionValues._ val anOption = Some(18) // Use OptionValues to check Option's value, using assert assert(anOption.value > 9) import Matchers._ val anOption = Some(18) // Use OptionValues to check Option's value, using Matchers syntax anOption.value should be > 9 |
|||||
EitherValues | |||||
import org.scalatest._ import EitherValues._ val either1: Either[String, Int] = Right(16) // Use EitherValues to check left and right value assert(either1.right.value > 9) // of an Either, using assert val either2: Either[String, Int] = Left("Muchas problemas") assert(either2.left.value == "Muchas problemas") import Matchers._ val either1: Either[String, Int] = Right(16) // Use EitherValues to check left and right value either1.right.value should be > 9 // of an Either, using Matchers syntax val either2: Either[String, Int] = Left("Muchas problemas") either2.left.value should be ("Muchas problemas") | |||||
PartialFunctionValues | |||||
import org.scalatest._ import PartialFunctionValues._ val map = Map("one" -> 1, "two" -> 2, "three" -> 3) // Use PartialFunctionValues to check value of a assert(map.valueAt("two") == 2) // PartialFunction, using assert import Matchers._ val map = Map("one" -> 1, "two" -> 2, "three" -> 3) // Use PartialFunctionValues to check value of a map.valueAt("two") should equal (2) // PartialFunction, using Matchers syntax | |||||
PrivateMethodTester | |||||
import org.scalatest.PrivateMethodTester._ class TaxCalculator { // Use PrivateMethodTester to invoke a private private def calc(amount: Double, percentage: Double): Double = // method for testing purpose amount * percentage / 100.00 def calculateTax(amount: Double): Double = calc(amount, 5.00) } val calculator = new TaxCalculator val calcMethod = PrivateMethod[Double]('calc) calculator invokePrivate calcMethod(1000.00, 8.88) |
be
be
matchershave
Option
and Either
"containers"
"aggregations"
"sequences"
iterators
File
and
, or
, and not
ScalaTest is brought to you by Bill Venners and Artima.
ScalaTest is free, open-source software
released under the Apache
2.0 license.
If your company loves ScalaTest, please consider sponsoring the project.
Copyright © 2009-2024 Artima, Inc. All Rights Reserved.