Java 使用对象实例化测试代码段的良好实践

Java 使用对象实例化测试代码段的良好实践,java,unit-testing,testing,kotlin,Java,Unit Testing,Testing,Kotlin,是否有任何指导方针(或最佳实践)将以下内容进行整理 我有以下测试方法: fun findProfileByPersonalInfo(personInfo: PersonalInfo): Profile? { localProfileRepository.findByPersonalInfo(personalInfo)?.let { return it } val searchParams = RemoteProfileSearchParameters()

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

我有以下测试方法:

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
}
当我开始为此函数编写单元测试时,我意识到:

  • 测试line
    val profile=profileFactory.create(remoteProfile)
    既简单又方便,因为我可以模拟此调用的结果,并分别测试从
    remoteProfile
    profile
    的映射。这样,如果我更改映射逻辑,我就不会破坏对
    findProfileByPersonalInfo
    的测试,这很好
  • 反之亦然,如果从
    personalInfo
    映射到
    searchParams
    的逻辑属于
    findProfileByPersonalInfo
    ,那么维护测试就不正确,也很困难
  • 问题是:

  • 总是(几乎)将实例化逻辑从被测函数中移出以使其更易于测试和维护,这样可以吗?毫无疑问,这方面的例外是函数,它们唯一的职责是实例化对象
  • 为上述情况下的每个对象创建某种类型的工厂不是太过分了吗?系统的整体设计似乎因此受到影响 非常感谢您对最佳实践或讨论的任何参考。多谢各位

  • 这有点宽泛,一般来说,您希望方法不要做太多工作,并将代码的可重用部分移动到单独的方法中。基于您展示的有限上下文,在本例中,出于可测试性和可读性的原因,我肯定会将实例化移出

  • 您并不总是需要一个完整的工厂,这取决于上下文,一个简单的构造函数
    RemoteProfileSearchParameters(personInfo:PersonalInfo)
    在这里可能是最明智的。根据复杂性的不同,这可能会被重构为一个工厂方法或一个实际的工厂对象,但通常这不会是您的第一步


  • 谢谢你的回复,我大体上同意你的看法。但是,在构造函数的情况下,如何测试实例化逻辑(即使可以用一些框架模拟构造函数,这也是一个“否”)?您只需实例化所述类的一个对象,并根据构造函数中提供的输入确认该对象的行为符合预期。嘲笑是没有意义的,因为你会嘲笑你想要测试的东西,从而测试你的嘲笑。如果在测试中调用构造函数是不可能的,例如由于外部依赖关系,那么您将希望在主代码中注入这些依赖关系,并在测试中模拟这些依赖关系。