将模拟与 apply R 结合使用
Using mocking with apply R
我目前正在使用包 testthat
和 mockery
在一些单元测试中进行模拟。我试图了解当使用 apply
在函数中实际调用模拟函数时,mockery
包中的函数 expect_args
是如何工作的。下面是测试成功的例子
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,])
相关联的参数名称。
首先,我很高兴这个小工具变得有用!其次,您看到的错误源于您的转换是如何进行的以及 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
所以你可以看到在第一次调用中传递了一个named raw,第二次调用也是如此——有names分配给每一列。这是因为 as.matrix
保留了列名。所以这不是关于 argument 名称,这是关于比较的 data 中的名称。
现在,当您 运行 使用 expect_args
进行最终比较时,您实际上使用的是 as.double
,它不保留名称。因此,您看到的错误。要修复它,您只需将您的期望更改为:
expect_args(m, 1, as.matrix(myMat)[1,])
希望这能解决您的问题。
我目前正在使用包 testthat
和 mockery
在一些单元测试中进行模拟。我试图了解当使用 apply
在函数中实际调用模拟函数时,mockery
包中的函数 expect_args
是如何工作的。下面是测试成功的例子
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,])
相关联的参数名称。
首先,我很高兴这个小工具变得有用!其次,您看到的错误源于您的转换是如何进行的以及 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
所以你可以看到在第一次调用中传递了一个named raw,第二次调用也是如此——有names分配给每一列。这是因为 as.matrix
保留了列名。所以这不是关于 argument 名称,这是关于比较的 data 中的名称。
现在,当您 运行 使用 expect_args
进行最终比较时,您实际上使用的是 as.double
,它不保留名称。因此,您看到的错误。要修复它,您只需将您的期望更改为:
expect_args(m, 1, as.matrix(myMat)[1,])
希望这能解决您的问题。