Использование насмешки с применением R
Я в настоящее время издеваюсь в некоторых модульных тестах, используя пакеты testthat
а также mockery
, Я пытаюсь понять, как работает функция expect_args
от mockery
Пакет работает, когда макетная функция фактически вызывается в функции, используя apply
, Вот пример, где тест пройден успешно.
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
пакет. Тем не менее мне не удается найти, с каким именем аргумента мне следует ассоциировать as.double(myMat[1,])
,
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
Таким образом, вы можете видеть, что в первом вызове был передан один с именем raw, и то же самое верно для второго вызова - для каждого столбца назначены имена. Это потому что as.matrix
сохраняет имена столбцов. Так что речь идет не об именах аргументов, а об именах в сравниваемых данных.
Теперь, когда вы запускаете окончательное сравнение, используя expect_args
вы на самом деле используете as.double
который не сохраняет имена. Таким образом, ошибка, которую вы видите. Чтобы это исправить, вы можете просто изменить свое ожидание на:
expect_args(m, 1, as.matrix(myMat)[1,])
Я надеюсь, что это решит вашу проблему.