2016-12-06 38 views
1

我目前正在嘲笑一些單元測試,使用包testthatmockery。我試圖瞭解mockery包中的函數expect_args如何在使用apply的函數中實際調用模擬函數時工作。這裏是一個測試成功的例子。使用模擬與應用R

myMean <- function(A){ 
apply(A,1,mean) 
} 

myMat = matrix(rep(1,6), nrow = 2, ncol = 3) 
test_that("myMean calls base::mean correctly",{ 
m <- mock(1, cycle = TRUE) 
with_mock(
`base::mean` = m, 
    myMean(myMat), 
    expect_args(m, 1, as.double(myMat[1,]))) 
}) 

讓我們現在稍微複雜一點的例子,其中myMean的說法實際上是一個data.frame,需要轉化爲函數內的一個矩陣。

myMean <- function(A){ 
B = as.matrix(A) 
apply(B,1,mean) 
} 

myMat = as.data.frame(myMat) 
test_that("myMean calls base::mean correctly",{ 
m <- mock(1, cycle = TRUE) 
with_mock(
`base::mean` = m, 
    myMean(myMat), 
expect_args(m, 1, as.double(myMat[1,]))) 
}) 

然後我收到以下錯誤信息:

Error: Test failed: 'myMeanSimple calls base::mean correct number of times   
* 1st actual argument not equal to 1st expected argument. 
names for target but not for current 

此錯誤是在mockery包的vignette解釋。儘管如此,我無法找到我應該與as.double(myMat[1,])聯繫的參數名稱。

回答

2

首先,我很高興這個小工具變得有用!其次,你看到的錯誤是由你的轉換過程如何產生的,以及expect_args如何比較結果。在內部,我們呼叫expect_equal,要求所有matrix的名稱都在那裏。

呼喚你的第二個例子後,我運行此:

> mock_args(m) 
[[1]] 
[[1]][[1]] 
V1 V2 V3 
1 1 1 

[[2]] 
[[2]][[1]] 
V1 V2 V3 
1 1 1 

所以你可以看到,在第一次調用一個命名爲生獲得通過,並同樣適用於第二個電話 - 有名稱分配給每列。這是因爲as.matrix保留了列名。所以這與的名稱名稱不同,這是關於名稱的數據的比較。

現在,當您使用expect_args進行最終比較時,您實際上使用的是as.double,它不保留名稱。因此,你看到的錯誤。要修復它,你可以簡單地改變你的期望:

expect_args(m, 1, as.matrix(myMat)[1,]) 

我希望這可以解決您的問題。

+0

是的。非常感謝你。 –