# Testing in Android

# Unit Testing

- It is used to refer to simple tests. like - simple business logic test independent of any fragment or activity.

## Library Used

- testImplementation "com.google.truth:truth:1.0.1"

- use 
```import com.google.common.truth.Truth.assertThat
```  instead of 
```import org.junit.Assert.*
``` 


## Implementation

- Use a class. Inside that class create one function that returns boolean values based on different input given.

```
object RegistrationUtil {

    private val existingRollNos = listOf("123", "456")
    
    fun validateRegistrationInput (
        student_name: String,
        roll_no: String,
    ) : Boolean {
        if(student_name.isEmpty() || roll_no.isEmpty()) {
            return false
        }
        if(roll_no in existingRollNos) {
            return false
        }

        return true
    }
}
``` 

- to generate a test class you need to right-click on class -> generate -> provide test class name and lib -> press ok.

- Inside the test class, you can create diff test funcs using @Test annotation. Inside
func provide diff inputs to validation func store that response in variable and check that response against desired value using assertThat method.

```
class RegistrationUtilTest {

    @Test
    fun `empty name return false`() {
        val result = RegistrationUtil.validateRegistrationInput(
            "",
            "678"
        )
        assertThat(result).isFalse()
    }
}
``` 

- That's it you are done now run the tests. If you get the same response as the desired result. Your test will pass otherwise it will fail. 

- In the above example it will return false if the student name or roll is not given or roll
already exist.

## Good test

- A good test is one that is completely independent of other test cases. eg - It will not share any global variable or like each test case will define its own variable.

## @Before and @After

- Jnuit provides this method in order to reduce code for each test case. Suppose there is a code common for every test case. Then you can define a setup function and annotate it with @Before. It will execute the code before every test case and your test case will run normally. Similarly, @After has teardown fun and you can write code that you want to run after every test case. like - destroying objects, the closing of room database, etc.


```
class ResourceComparerTest {

    private lateinit var resourceComparer: ResourceComparer

    @Before
    fun setup() {
        resourceComparer = ResourceComparer()
    }

    @After
    fun teardown() {
        
    }

    @Test
    fun stringResourceSameAsGivenString_returnsTrue() {
//        resourceComparer = ResourceComparer()
        val context = ApplicationProvider.getApplicationContext<Context>()
        val result = resourceComparer.isEqual(context, R.string.app_name, "testing")
        assertThat(result).isTrue()
    }
}
``` 
## Function Naming

- In a unit test, we can write long func names with spaces in between

```
@Test
fun `empty name return false`() 
``` 

- We cannot do this in other Tests there we have to name func like we normally do

```
@Test
fun insertShoppingItem()
``` 












# Refrences

- https://youtu.be/W0ag98EDhGc

