Reputation: 135
I am currently mocking in some unit tests, using the packages testthat
and mockery
. I am trying to understand how the function expect_args
from the mockery
package works when the mocked function is actually called in a function using apply
. Here is an example where the test is successful.
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,])))
})
Let's take now a slightly more complicated example, where the argument of myMean
is actually a data.frame
and needs to be converted to a matrix within the function.
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,])))
})
I then get the following error message:
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
This error is explained on the vignette of the mockery
package. Nevertheless I do not manage to find which argument name I should associate with as.double(myMat[1,])
.
Upvotes: 2
Views: 234
Reputation: 148
First of all, I'm happy this small utility became useful! Second of all, the error you see results from how your transformations are carried out and how expect_args
compares results. Internally, we call expect_equal
which requires all of the names of the matrix
to be present there.
After calling your second example I run this:
> mock_args(m)
[[1]]
[[1]][[1]]
V1 V2 V3
1 1 1
[[2]]
[[2]][[1]]
V1 V2 V3
1 1 1
So you can see that in the first call a single named raw was passed, and the same is true for the second call - there are names assigned to each column. This is because as.matrix
preserves column names. So this is not about argument names, this is about names in the data that's compared.
Now, when you run your final comparison using expect_args
you actually use as.double
which doesn't preserve names. Thus, the error you see. To fix it you can simply change your expectation to:
expect_args(m, 1, as.matrix(myMat)[1,])
I hope this solves your problem.
Upvotes: 3