Creating a flawed UserManager

Using interfaces to define the dependencies of our code will allow us to provide mocks during the tests. Let's start by defining a basic DataSource interface that contains the methods that will be used concurrently:

interface DataSource {
fun getNameAsync(id: Int): Deferred<String>
fun getAgeAsync(id: Int): Deferred<Int>
fun getProfessionAsync(id: Int): Deferred<String>
}

Now, let's define a data class that will be the return type of the functionality we want to test. In this case, we just need a simple class:

data class User(
val name: String,
val age: Int,
val profession: String
)

And finally, let's add UserManager, which has the functionality that we want to test. This class contains a method that calls datasource in order to retrieve all the different chunks of information, then it compiles that together and returns User:

class UserManager(private val datasource: Datasource) {
suspend fun getUser(id: Int): User {
val name = datasource.getNameAsync(id)
val age = datasource.getAgeAsync(id)
val profession = datasource.getProfessionAsync(id)

// Wait for profession, since it "will" take longer
profession.await()

return User(
name.getCompleted(),
age.getCompleted(),
profession.getCompleted()
)
}
}

In this first implementation, we have decided that we will only suspend while profession is being obtained. This decision is made because we know that profession will always take longer to be retrieved since it's coming from an external system. Now, let's add some tests to validate that it works.

If you follow Test-Driven Development (TDD), you would write the tests before writing the code. In this case, I did it in this order because it seemed to me that it would be more simple to understand what we are doing this way.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.69.163