【问题标题】:Is it possible to temporarily replace one class with another?是否可以暂时将一个班级替换为另一个班级?
【发布时间】:2017-01-10 21:52:09
【问题描述】:

我正在为从Patient 类的实例获取各种信息的方法编写单元测试。 Patient 类是一个非常复杂的容器,围绕着一堆其他东西,它可以通过像patient.demographics.firstName 这样的操作轻松获取信息。如果不将我的单元测试转变为集成测试,就不可能创建一个“真正的”患者。

显而易见的解决方案是将Patient 替换为Map。如果这是 Python,我可以做 Patient = dict 并继续我的生活,但我无法在 Groovy 中找到任何等价物==我能找到的只是替换方法。从有关在 Groovy 中测试的少量信息来看,我似乎可以使用地图强制作为过于复杂的替代品,但我认为这是最后的手段。

有问题的代码是Patient lpatient = app.createLegacyPatient(payload.patientId.toLong()),我已经模拟了 createLegacyPatient 方法以返回地图。问题是,Map 对象不是 Patient 对象,尝试将其强制转换为 Patient 是行不通的。

在 Groovy 中有什么方法可以说“这个类现在是另一个类,直到我说不同?”换句话说,有没有可能让new Patient() 实际上返回一个Map 对象?

【问题讨论】:

  • 这真的取决于,因为 Groovy 可以创建代理,但代理并不总是被“欺骗”的代码所接受。请发布一个使用Patient 的代码示例,而Map 是不够的。
  • 我真的不能发布比我拥有的更多的东西(这是为了工作),但问题的答案似乎很明显是“不”。无论如何,我最终通过将Patient lpatient 更改为def lpatient 来避免这个问题。我最初不愿意这样做,因为那是由我作为承包商的公司的一名正式员工编写的代码,但是,嗯......静态类型很糟糕。

标签: groovy


【解决方案1】:

Groovy 带有一个 Expando 类,我认为它会满足您的需求。这是一个例子:

def patient = new Expando()

patient.demographics = [ firstName : "John", lastName : "Galt" ]

assert patient.demographics.firstName == "John"

您也可以使用Map 初始化Expando

def map = [
    demographics : [
        firstName : "John", lastName : "Galt" 
    ]
]

def patient = new Expando(map)

assert patient.demographics.firstName == "John"

在许多情况下,只需使用 Map 就足够了:

def patient = [
    demographics : [
        firstName : "John", lastName : "Galt" 
    ]
]

assert patient.demographics.firstName == "John"

【讨论】:

  • 我想我的问题不清楚。我已经更新了它。我尝试传递一个 Expando,但遇到了同样的问题。
【解决方案2】:

是的,映射强制是 Groovy 中模拟对象的首选方式

def patient = [
   demographics : [
      firstName : "John", lastName : "lennon" 
   ]
] as Patient

assert patient.demographics.lastName == "lennon"

仅此而已。您刚刚使用 Python 中的 Map 创建了一个 Patient 对象

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 2016-06-06
    • 2018-07-24
    相关资源
    最近更新 更多