2016-12-06 37 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

是的。非常感谢你。 –