ideas icon indicating copy to clipboard operation
ideas copied to clipboard

A Java tool using Spring that records JUnit + Mockito unit/integration tests from runtime calls

Open ibreaz opened this issue 3 years ago • 0 comments

Project description

I imagine this tool would work like this: You mark a method with an @RecordTest annotation. You mark some injected dependencies with @RecordMockForTest annotation. You run the project and interact with UI/API. Context, arguments and results are retrieved using Aspect Oriented Programing and Reflection and used to generate a test for each function call in the console or to a disk file.

I know Test Driven Development is a great way to write software, but there are cases when generating a test from existing code might still be needed for various reasons: - when you want to maintain code that does not have unit tests and want to be sure you don't introduce new bugs - when for some reason in your company there is no time/budget/culture/wiliness to do TDD, but having generated tests is still better than no tests - when the tests and mocks are long and hard to write and you could use a jumpstart - when you are doing big changes in the design and a lot of the tests need to be rewritten - when you want to record a functional test with real data from UI

Example: Let's say you have some function for calculating Employee salary that does not have automated tests yet:

public class SalaryService {
	public double computeEmployeeSalary(int employeeId) throws Exception {
		// ...
		Employee employee = employeeRepository.getEmployee(employeeId);
		// ...
		return salary;
	}
}

public class EmployeeRepository {
	public Employee getEmployee(int id) throws Exception {
		// ...
		// Get Employee data from DB
		// ...
		return employee;
	}
}
			
			

You add @RecordTest to computeEmployeeSalary function to mark that you want tests generated from the calls to this function. You add @RecordMockForTest to EmployeeRepository class to mark that you want this class mocked in the tests. You interact with the UI/API and the computeEmployeeSalary function is called with real data.

The resulted test will be like this (depending on the real data):

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
import com.sampleapp.model.Department;
import com.sampleapp.model.Employee;
import com.sampleapp.services.EmployeeRepository;
import static org.mockito.Mockito.*;

class SalaryServiceTest {
	@Test
	void computeEmployeeSalary() throws Exception {
		// Arrange
		Department department1 = Department.builder()
			.id(100)
			.name("IT")
			.build();
		Employee employee1 = Employee.builder()
			.id(1)
			.firstName("Doe")
			.lastName("John")
			.department(department1)
			.salaryParam1(1000.0)
			.salaryParam2(1500.0)
			.salaryParam3(200.0)
			.build();
		EmployeeRepository employeeRepository = mock(EmployeeRepository.class);
		when(employeeRepository.getEmployee(1)).thenReturn(employee1);
		SalaryService salaryService = new SalaryService(employeeRepository);

		// Act
		double result = salaryService.computeEmployeeSalary(1);

		// Assert
		assertEquals(4000.0, result);
	}
}

I already have a prof of concept for this and it would be very helpful for me to hear your opinions before investing more effort in this direction.

Relevant Technology

Java, Spring, JUnit, Mockito

Complexity and required time

Complexity

  • [ ] Beginner - This project requires no or little prior knowledge of the technolog(y|ies) specified to contribute to the project
  • [x] Intermediate - The user should have some prior knowledge of the technolog(y|ies) to the point where they know how to use it, but not necessarily all the nooks and crannies of the technology
  • [ ] Advanced - The project requires the user to have a good understanding of all components of the project to contribute

Required time (ETA)

  • [ ] Little work - A couple of days
  • [x] Medium work - A week or two
  • [ ] Much work - The project will take more than a couple of weeks and serious planning is required

Categories

  • [ ] Mobile app
  • [ ] IoT
  • [ ] Web app
  • [ ] Frontend/UI
  • [ ] AI/ML
  • [ ] APIs/Backend
  • [ ] Voice Assistant
  • [x] Developer Tooling
  • [ ] Extension/Plugin/Add-On
  • [ ] Design/UX
  • [ ] AR/VR
  • [ ] Bots
  • [ ] Security
  • [ ] Blockchain
  • [ ] Futuristic Tech/Something Unique

ibreaz avatar May 12 '21 17:05 ibreaz