What is Unit Testing?
Unit testing involves testing individual units of code to ensure they perform as expected. A unit can be a single function, a method, or a class. By isolating each part of the program, unit tests can help detect issues early in the development cycle.
Need Debugging? – Try RobotQA and Start Debugging on Real Devices. Download Plugin
Why Unit Testing?
- Early Bug Detection: Catch bugs early before they make it into production.
- Documentation: Tests act as a form of documentation that explains how the code is supposed to work.
- Refactoring Safety: Ensure that changes in code do not break existing functionality.
- Simplified Debugging: Isolate specific parts of the codebase to test in isolation.
Setting Up Your Android Project for Unit Testing
- Add Dependencies: Ensure your
build.gradle
file includes the necessary dependencies for JUnit and Mockito.
1 2 3 4 5 |
dependencies { testImplementation 'junit:junit:4.13.2' testImplementation 'org.mockito:mockito-core:3.11.2' testImplementation 'org.mockito:mockito-inline:3.11.2' } |
- Directory Structure: Create a directory named
test
undersrc
to place your unit test files. This is where you'll write your test cases.
1 2 3 4 5 6 |
- src - main - test - java - com - yourpackage |
Writing Your First Unit Test
Let's consider a simple example where we have aCalculator
class with a method add(int a, int b)
that returns the sum of two integers.
Calculator.java
1 2 3 4 5 |
public class Calculator { public int add(int a, int b) { return a + b; } } |
1 2 3 4 5 6 7 8 9 10 11 |
import static org.junit.Assert.assertEquals; import org.junit.Test; public class CalculatorTest { @Test public void testAdd() { Calculator calculator = new Calculator(); int result = calculator.add(2, 3); assertEquals(5, result); } } |
- Explanation:
@Test
annotation marks thetestAdd
method as a test case.assertEquals
is used to assert that the expected value (5) matches the actual value returned by theadd
method.
Writing Tests with Mockito
Mockito is a powerful mocking framework that allows you to create and configure mock objects for testing. Suppose you have aUserService
class that depends on a UserRepository
interface.
UserService.java
1 2 3 4 5 6 7 8 9 10 11 |
public class UserService { private UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } public User getUserById(int id) { return userRepository.findById(id); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
import static org.mockito.Mockito.*; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; public class UserServiceTest { @Mock private UserRepository userRepository; private UserService userService; @Before public void setUp() { MockitoAnnotations.initMocks(this); userService = new UserService(userRepository); } @Test public void testGetUserById() { User mockUser = new User(1, "John Doe"); when(userRepository.findById(1)).thenReturn(mockUser); User user = userService.getUserById(1); assertEquals("John Doe", user.getName()); } } |
- Explanation:
@Mock
annotation creates a mock instance ofUserRepository
.MockitoAnnotations.initMocks(this)
initializes the mock objects.when(...).thenReturn(...)
sets up the behavior of the mock object.assertEquals
asserts that the returned user's name matches the expected value.
Running Your Unit Tests
You can run your unit tests directly from Android Studio:- Right-click on the test file or directory in the Project view.
- Select
Run 'Tests in ...'
.
1 |
./gradlew test |