R中for循环内的模拟函数

问题描述

我在 R 中使用 testthat 包进行单元测试。我有一个函数 CalcByResultSubModel,它还有一个函数 CalculateX,它在主函数中被调用。这是主要功能


CalcByResultSubModel = function(doll_data,fn_master,modelPath) {
  # load sub model result
  load(modelPath)
  
  # calculation
  for(abc in c("ABC",fn_master$fn_a)) {
    
    # columns
    col_name = paste0("x",abc)    
    iterModel = resultSubmodel[[abc]]
    
    # calculate yhat X
    doll_data[,col_name] = iterModel %>% 
      purrr::map(.,function(imodel) {
        CalculateX(data,imodel)
      }) %>% 
      as.data.frame(.) %>%
      apply(.,1,mean)
    
    message(paste(col_name,"calculated"))      
  }

这是函数CalculateX

CalculateX = function(data,model) {
  iterData = data %>% 
    dplyr::select(model$feature_names) %>% 
    as.matrix(.)
  set.seed(131)
  result = predict(model,iterData,missing = NA)
  result = matrix(result,2)[2,]
  
  return(result)
}

为了执行单元测试,我们必须模拟函数 CalculateX。但这里的复杂之处在于,该函数是在主函数的 for 循环中调用的。在我的单元测试中,我对这个场景很陌生。任何人都可以帮助我模拟 for 循环中的函数吗?这是模拟的代码,我试过了。

local_mock(CalculateX = function(data,model){
                  for (abc in c("ABC",fn_master$fn_a)
                  case_when(
                    abc == "feature1" ~ .ReadCsvWrapper("feature1.csv"),abc == "feature2" ~ .ReadCsvWrapper( "feature2.csv"),abc == "feature3" ~ .ReadCsvWrapper("feature3.csv"))
            })
But the above approach doesn't seem to work for me. Can anyone help me with this?

解决方法

您的代码中有几个问题。首先,CalcByResultSubModel 在循环中调用 CalculateX

for(abc in c("ABC",fn_master$fn_a)) {
    
    # columns
    col_name = paste0("x",abc)    
    iterModel = resultSubmodel[[abc]]
    
    # calculate yhat X
    doll_data[,col_name] = iterModel %>% 
      purrr::map(.,function(imodel) {
        CalculateX(data,imodel)
      }) %>% 
      as.data.frame(.) %>%
      apply(.,1,mean)
    
    message(paste(col_name,"calculated"))      
  }

所以你不需要把 for(abc in c("ABC",fn_master$fn_a)) 放入模拟函数中。只需将其设置为返回与调用实际函数类似的结果即可。

第二个问题是,在真正的 CalculateX 中,您有 set.seed(131)。这几乎肯定是一个坏主意。每次调用 CalculateX 时,它都会将随机数生成器重置为固定设置,这使其完全非随机,并且之后还会调用随机数函数重复其输出。

在测试脚本的顶部设置一次种子通常是一个好主意,这样测试是可预测的,但像您一样经常重置它不是。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...