2016-12-06 2 views
1

В настоящее время я издевательски разбираюсь в некоторых модульных тестах, используя пакеты testthat и mockery. Я пытаюсь понять, как функция expect_args из пакета mockery работает, когда функция издевательства фактически вызывается функцией, используя 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 

Эта ошибка объясняется на vignette из mockery пакета. Тем не менее мне не удается найти имя аргумента, которое я должен связать с 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

Да, так оно и есть. Большое спасибо. –

Смежные вопросы