带有模拟对象的 ScalaTest
ScalaTest with mocked object
我找到了一些简单的示例,但没有任何效果。
一个模型:
class Product() {
var price: Int = 0
var stock: Int = 0
def addPrice(price: Int): Int = {
this.price = price
this.price
}
def addStock(qty: Int): Int = {
this.stock += qty
this.stock
}
}
和我的测试class
classProductSpec extends AnyFlatSpec with MockFactory with OneInstancePerTest {
val m = mock[Product]
// suites (test examples)
inAnyOrder {
(m.addPrice _).expects(40).returns(40).once
inSequence {
(m.addStock _).expects(20).returns(20).once
(m.addStock _).expects(10).returns(30).once
}
}
// tests
it should "set price" in {
assert(m.addPrice(40) == 40)
}
it should "add new qty. Step 1" in {
assert(m.addStock(20) == 20)
}
it should "add new qty. Step 2" in {
assert(m.addStock(10) == 30)
}
}
每次,错误是:
Expected:
inAnyOrder {
inAnyOrder {
<mock-1> Product.addPrice(40) once (never called - UNSATISFIED)
...
}
}
如果我 运行 只有一套套件和一个断言,它有效:
(m.addPrice _).expects(40).returns(40).once
// tests
it should "set price" in {
assert(m.addPrice(40) == 40)
}
我们来解释一下上面的代码。 inAnyOrder
部分为所有测试定义断言。这意味着,在套件中的每个测试中,您应该恰好调用一次:
m.addPrice(40)
m.addStock(20)
m.addStock(10)
while 2 must come before 3. 因此,由于缺少 2 个调用,每个测试都失败了。例如测试:
it should "add new qty. Step 1" in {
assert(m.addStock(20) == 20)
}
失败并显示消息:
Expected:
inAnyOrder {
inAnyOrder {
<mock-1> Product.addPrice(40) once (never called - UNSATISFIED)
inSequence {
<mock-1> Product.addStock(20) once (called once)
<mock-1> Product.addStock(10) once (never called - UNSATISFIED)
}
}
}
Actual:
<mock-1> Product.addStock(20)
ScalaTestFailureLocation: ProductSpec at (ProductSpec.scala:20)
org.scalatest.exceptions.TestFailedException: Unsatisfied expectation:
因为1和3都不满意
如果您尝试这样的测试:
it should "set price" in {
assert(m.addPrice(40) == 40)
assert(m.addStock(20) == 20)
assert(m.addStock(10) == 30)
}
会过去的。
请注意,如果更改 2 和 3 的顺序,相同的测试将失败。
我找到了一些简单的示例,但没有任何效果。
一个模型:
class Product() {
var price: Int = 0
var stock: Int = 0
def addPrice(price: Int): Int = {
this.price = price
this.price
}
def addStock(qty: Int): Int = {
this.stock += qty
this.stock
}
}
和我的测试class
classProductSpec extends AnyFlatSpec with MockFactory with OneInstancePerTest {
val m = mock[Product]
// suites (test examples)
inAnyOrder {
(m.addPrice _).expects(40).returns(40).once
inSequence {
(m.addStock _).expects(20).returns(20).once
(m.addStock _).expects(10).returns(30).once
}
}
// tests
it should "set price" in {
assert(m.addPrice(40) == 40)
}
it should "add new qty. Step 1" in {
assert(m.addStock(20) == 20)
}
it should "add new qty. Step 2" in {
assert(m.addStock(10) == 30)
}
}
每次,错误是:
Expected:
inAnyOrder {
inAnyOrder {
<mock-1> Product.addPrice(40) once (never called - UNSATISFIED)
...
}
}
如果我 运行 只有一套套件和一个断言,它有效:
(m.addPrice _).expects(40).returns(40).once
// tests
it should "set price" in {
assert(m.addPrice(40) == 40)
}
我们来解释一下上面的代码。 inAnyOrder
部分为所有测试定义断言。这意味着,在套件中的每个测试中,您应该恰好调用一次:
m.addPrice(40)
m.addStock(20)
m.addStock(10)
while 2 must come before 3. 因此,由于缺少 2 个调用,每个测试都失败了。例如测试:
it should "add new qty. Step 1" in {
assert(m.addStock(20) == 20)
}
失败并显示消息:
Expected:
inAnyOrder {
inAnyOrder {
<mock-1> Product.addPrice(40) once (never called - UNSATISFIED)
inSequence {
<mock-1> Product.addStock(20) once (called once)
<mock-1> Product.addStock(10) once (never called - UNSATISFIED)
}
}
}
Actual:
<mock-1> Product.addStock(20)
ScalaTestFailureLocation: ProductSpec at (ProductSpec.scala:20)
org.scalatest.exceptions.TestFailedException: Unsatisfied expectation:
因为1和3都不满意
如果您尝试这样的测试:
it should "set price" in {
assert(m.addPrice(40) == 40)
assert(m.addStock(20) == 20)
assert(m.addStock(10) == 30)
}
会过去的。 请注意,如果更改 2 和 3 的顺序,相同的测试将失败。