我有一個方法,其中包括生成一個識別符號,將其發送到某個外部依賴項并回傳它。我想要一個單元測驗來測驗是否回傳了相同的值。
假設測驗和代碼如下所示:
def "test"() {
given:
def testMock = Mock(TestMock)
and:
def x
when:
def testClass = new TestClass()
x = testClass.callMethod(testMock)
then:
1 * testMock.method(x)
}
static interface TestMock {
void method(double x)
}
static class TestClass {
double callMethod(TestMock mock) {
double x = Math.random()
mock.method(x)
return x
}
}
代碼作業正常,但是測驗失敗并顯示一條訊息:
One or more arguments(s) didn't match:
0: argument == expected
| | |
| | null
| false
0.5757686318956925
所以看起來模擬簽入then是在when塊中分配值之前完成的。
有沒有辦法讓 Spock 在檢查模擬呼叫之前分配這個值?或者我可以用不同的方式做這個檢查嗎?
我唯一的想法是將 id-generator 注入方法(或實際上注入類)并在測驗中存根它,但這會使代碼復雜化,我想避免它。
我根據 kriegaex 評論修復了代碼示例。
uj5u.com熱心網友回復:
修復示例代碼
在開始之前,您的示例代碼存在兩個問題:
1 * testMock(x)應該1 * testMock.method(x)callMethod應該回傳double,而不是int,否則結果將始終為 0 (0 和 1 之間的雙精度在轉換為整數時總是產生 0 )。
下次請確保您的示例代碼不僅可以編譯,而且可以執行預期的操作。示例代碼只有在沒有額外錯誤的情況下才有用,試圖幫助您的人需要先修復這些錯誤,然后才能稍后專注于實際問題。
手頭的問題
正如您已經注意到的,互動,即使是在一個then:塊中的詞法定義,也會通過 Spock 的編譯器 AST 轉換以這樣一種方式進行轉換,即當模擬初始化時,它們會在模擬上注冊。這是必要的,因為模擬必須在呼叫when:塊中的任何方法之前準備好。在已經執行該塊的同時嘗試直接使用稍后才知道的結果when:,將導致您描述的問題。首先是雞肉還是雞蛋?在這種情況下,您不能使用另一個方法呼叫約束中的模擬方法的未來結果來指定方法引數約束。
解決方法
一種可能的解決方法是存根方法并在計算存根結果的閉包中捕獲引數,例如>> { args -> arg = args[0]; return "stubbed" }. 當然,return關鍵字是 Groovy 中閉包或方法的最后一條陳述句是多余的,在您的情況下,方法是void,因此您根本不需要回傳任何內容。
一個例子
我修改了您的示例代碼,重命名了類、方法和變數,以更清楚地描述發生了什么以及正在發生什么:
package de.scrum_master.stackoverflow.q72029050
import spock.lang.Specification
class InteractionOnCallResultTest extends Specification {
def "dependency method is called with the expected argument"() {
given:
def dependency = Mock(Dependency)
def randomNumber
def dependencyMethodArg
when:
randomNumber = new UnderTest().getRandomNumber(dependency)
then:
1 * dependency.dependencyMethod(_) >> { args -> dependencyMethodArg = args[0] }
dependencyMethodArg == randomNumber
}
}
interface Dependency {
void dependencyMethod(double x)
}
class UnderTest {
double getRandomNumber(Dependency dependency) {
double randomNumber = Math.random()
dependency.dependencyMethod(randomNumber)
return randomNumber
}
}
在Groovy Web 控制臺中嘗試一下。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/468144.html
