FlatSpec is a good first step for teams wishing to move from xUnit to BDD. Its structure is flat like xUnit, so simple and familiar, but the test names must be written in a specification style: "X should Y," "A must B," etc. import org.scalatest._ import flatspec._ class SetSpec extends AnyFlatSpec { 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) } } // Define the first test for a subject, in this case: "An empty Set" "An empty Set" should "have size 0" in { // Name the subject, write 'should', then the rest of the test name assert(Set.empty.size == 0) // (Can use 'must' or 'can' instead of 'should') } it should "produce NoSuchElementException when head is invoked" in { // Define another test for the same intercept[NoSuchElementException] { // subject with 'it' Set.empty.head } } ignore should "be empty" in { // To ignore a test, change 'it' to 'ignore'... assert(Set.empty.isEmpty) } it should "not be non-empty" ignore { // ...or change 'in' to 'ignore' assert(!Set.empty.nonEmpty) } "A non-empty Set" should "have the correct size" in { // Describe another subject assert(Set(1, 2, 3).size == 3) } // 'it' now refers to 'A non-empty Set' it should "return a contained value when head is invoked" is (pending) // Define a pending test import tagobjects.Slow it should "be non-empty" taggedAs(Slow) in { // Tag a test assert(Set(1, 2, 3).nonEmpty) } } // Can also pass fixtures into tests with FixtureAnyFlatSpec class StringSpec extends FixtureAnyFlatSpec { type FixtureParam = String // Define the type of the passed fixture object override def withFixture(test: OneArgTest) = { // Shared setup (run before each test), including... val fixture = "a fixture object" // ...creating a fixture object try test(fixture) // Pass the fixture into the test finally { // Shared cleanup (run at end of each test) } } "The passed fixture" can "be used in the test" in { s => // Fixture passed in as s assert(s == "a fixture object") } } @DoNotDiscover // Disable discovery of a test class class InvisibleSpec extends AnyFlatSpec { /*code omitted*/ } @Ignore // Ignore all tests in a test class class IgnoredSpec extends AnyFlatSpec { /*code omitted*/ } import tags.Slow @Slow // Mark all tests in a test class with a tag class SlowSpec extends AnyFlatSpec { /*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 FlatSpec with WebBrowser with HtmlUnit { val host = "http://localhost:9000/" "The blog app home page" should "have the correct title" in { 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.