mercredi 11 mars 2020

Good practices to test piece of code with object instantiation

Is there any guidelines (or best practices) which puts in order the following?

I have the following method to test:

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
}

When I came to writing unit tests for this function I realized that:

  1. It is easy and convenient to test line val profile = profileFactory.create(remoteProfile) because I can mock the result of this call and test the mapping from remoteProfile to profile somewhere else separately. Having this, if I change the logic of mapping I won't break my test for findProfileByPersonalInfo, which is good.
  2. And vice versa, it feels not right and difficult to maintain the test if the logic of mapping from personalInfo to searchParams belongs to findProfileByPersonalInfo.

The questions are:

  1. Is it ok to (almost) always move instantiation logic from function under test to make it more testable and maintainable? Undoubtedly, the exception for this is functions whose only responsibility is to instantiate objects.
  2. Isn't it too much to create a some type of factory for each object that falls under the situation described above? It seems like the overall design of the system suffer because of this.

Any references to best practices or discussions are very appreciated. Thank you very much!

Aucun commentaire:

Enregistrer un commentaire