首页 > 解决方案 > 使用对象实例化测试一段代码的良好实践

问题描述

是否有任何指导方针(或最佳实践)来整理以下内容?

我有以下方法来测试:

fun findProfileByPersonalInfo(personInfo: PersonalInfo): Profile? {
    localProfileRepository.findByPersonalInfo(personalInfo)?.let {
        return it
    }
    val searchParams = RemoteProfileSearchParameters()
    //... Some mapping from personalInfo to searchParams
    remoteProfileRepository.findRemoteProfile(searchParams)?.let {
        val profile = profileFactory.create(remoteProfile)
        return save(profile)
    }
    return null
}

当我开始为这个函数编写单元测试时,我意识到:

  1. 测试线路既简单又方便,val profile = profileFactory.create(remoteProfile)因为我可以模拟此调用的结果并分别测试从其他地方remoteProfileprofile其他地方的映射。有了这个,如果我改变映射的逻辑,我不会破坏我的测试findProfileByPersonalInfo,这很好。
  2. 反之亦然,如果从映射personalInfo到的逻辑searchParams属于,感觉不太对,很难维护测试findProfileByPersonalInfo

问题是:

  1. (几乎)总是将实例化逻辑从被测函数中移动以使其更具可测试性和可维护性是否可以?毫无疑问,唯一的职责是实例化对象的函数是个例外。
  2. 为每个属于上述情况的对象创建某种类型的工厂是不是太过分了?系统的整体设计似乎因此受到影响。

非常感谢对最佳实践或讨论的任何参考。非常感谢!

标签: javaunit-testingtestingkotlin

解决方案


  1. 这有点宽泛,通常您希望方法不要做太多并将可重用的代码部分移动到单独的方法中。基于您展示的有限上下文,在这种情况下,出于可测试性和可读性的原因,我肯定会将实例化移出。

  2. 您并不总是需要一个成熟的工厂,根据上下文,一个简单的构造函数RemoteProfileSearchParameters(personInfo: PersonalInfo)可能是最明智的。根据复杂性,这可能会被重构为工厂方法或实际的工厂对象,但通常这不会是您的第一个 goto。


推荐阅读