Unit testing private methods inside of Android with Kotlin
Tags: android, mobile, kotlin, tristan
Published: 2024-03-12 05:17:16

### Table of contents
1. [How to unit test a private method](#how)
2. [Explanation](#ex)


### My app on the Google play store
- [The app](https://play.google.com/store/apps/details?id=elliott.software.clicker)

### GitHub code:
- [HERE](https://github.com/thePlebDev/Clicker/blob/master/app/src/main/java/com/example/clicker)

# 2024-06-03 update: To anyone reading this
- I don't like this post that I created. I would recommend you leave here and read my updated one.

- You can find the updated one : [HERE](https://dev.to/theplebdev/how-to-unit-test-a-private-method-in-kotlin-without-making-it-public-glc)


### How to unit test a private method inside of a ViewModel? <a name="how"></a>
- Obviously you can't unit test a method that you can't directly access. By definition, we can't access a private method. However, there are two ways to work around this:

`1)` Make the method public
`2)` Keep the method private but put the logic inside of a dependency's public method

- Since `Make the method public` is rather self explanatory, I will be explaining the second method

### Adding the logic inside of a dependency's public method <a name="ex"></a>
- Let's assume that this is our private method logic:
```kotlin
class StreamViewModel @Inject constructor(){

fun callingThePrivateMethodFromView(a:Int,b:Int){
        privateMethod(a,b)
    }

 private fun oldPrivateMethod(a:Int,b:Int): Int{
        //pretend this is advanced logic
        val answer =(a/b) * 45 -9
        return answer
    }
}

```
- Now because of the `advanced logic` inside of the `privateMethod()` method we want to be able to unit test it. To determine that the method is deterministic and does what we expect. Again, we can't do that with the private method so we have to do a few steps of refactoring.

- `1) create a new object to act as the dependency for a ViewModel`
```kotlin
class TokenMonitoring constructor(){

}

```
- `2) put advanced logic into public method`
```kotlin
class TokenMonitoringconstructor(){
 fun privateMethod(a:Int,b:Int): Int{
        //pretend this is advanced logic
        val answer =(a/b) * 45 -9
        return answer
    }

}

```

- `3) Inject into constructor and call from dependency`
```kotlin
class StreamViewModel constructor(
private val tokenMonitoring: TokenMonitoring= TokenMonitoring()
){

fun callingThePrivateMethodFromView(a:Int,b:Int){
        oldPrivateMethod(a,b)
    }
}

private fun oldPrivateMethod(a:Int,b:Int): Int{
        
        return tokenMonitoring.privateMethod(a,b)
    }

```

### How does this help with the unit testing?
- The unit testing of `privateMethod()` is now done through the `TokenMonitoring()` class. This means that we can unit test the `advanced logic` by accessing `tokenMonitoring.privateMethod(a,b)`. Which has the added factor of us now also being able to control the `TokenMonitoring()` when testing `StreamViewModel`

### Isn't this just the same as making it public?
- No! Making the method public would also give the View access to the method. By adding the logic into a public method of a dependency and then injecting that dependency, the view does not have access to this method and then old method can still stay private



### Conclusion
- Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on [Twitter](https://twitter.com/AndroidTristan).