Update Java test classes and methods to work with new code versions after refactoring or modifications. Use when code changes break existing tests due to signature changes, refactoring, or behavior modifications. Takes old and new code versions plus old tests as input, and outputs updated tests that compile and pass against the new code. Handles method signature changes, class refactoring, assertion updates, and mock modifications.
92
88%
Does it follow best practices?
Impact
100%
1.00xAverage score across 3 eval scenarios
Passed
No known issues
Automatically update Java test code to align with changes in production code, ensuring tests compile and pass after refactoring, signature changes, or behavior modifications.
Compare old and new versions of the production code to identify changes:
Read both versions:
Categorize changes:
Example change analysis:
// Old version
public double calculateDiscount(double price) {
return price * 0.1;
}
// New version
public double calculateDiscount(double price, double discountRate) {
if (discountRate < 0 || discountRate > 1) {
throw new IllegalArgumentException("Invalid discount rate");
}
return price * discountRate;
}Identified changes:
discountRateRead and understand the old test code:
Identify test structure:
@Before, @BeforeEach, @After, @AfterEach)Map tests to code changes:
Example old test:
@Test
public void testCalculateDiscount() {
double price = 100.0;
double result = calculator.calculateDiscount(price);
assertEquals(10.0, result, 0.01);
}Modify test code to match new method signatures:
For added parameters:
// Old call
calculator.calculateDiscount(price)
// Updated call
calculator.calculateDiscount(price, 0.1) // Use appropriate default or test valueFor removed parameters:
// Old call
calculator.calculateDiscount(price, taxRate, shippingCost)
// Updated call (if taxRate removed)
calculator.calculateDiscount(price, shippingCost)For parameter type changes:
// Old call
calculator.process(userId) // userId was int
// Updated call (if userId changed to Long)
calculator.process(Long.valueOf(userId))For renamed methods:
// Old call
calculator.computeTotal()
// Updated call (if renamed to calculateTotal)
calculator.calculateTotal()For moved methods:
// Old call
calculator.validateInput(data)
// Updated call (if moved to validator class)
validator.validateInput(data)Adjust test assertions to match new behavior:
For changed return values:
// Old assertion (10% fixed discount)
assertEquals(10.0, result, 0.01);
// Updated assertion (variable discount rate)
assertEquals(8.0, calculator.calculateDiscount(100.0, 0.08), 0.01);For new exceptions:
// Add new test for exception
@Test
public void testInvalidDiscountRate() {
assertThrows(IllegalArgumentException.class, () -> {
calculator.calculateDiscount(100.0, -0.1);
});
}For changed behavior:
// Old assertion
assertTrue(result.isEmpty());
// Updated assertion (if behavior changed to return null instead)
assertNull(result);For modified object state:
// Old assertion
assertEquals(1, cart.getItemCount());
// Updated assertion (if implementation changed)
assertEquals(1, cart.getItems().size());Modify mock objects to match new interfaces:
For Mockito mocks with signature changes:
// Old mock setup
when(repository.findById(userId)).thenReturn(user);
// Updated mock setup (if return type changed to Optional)
when(repository.findById(userId)).thenReturn(Optional.of(user));For added parameters in mocked methods:
// Old mock
when(service.process(data)).thenReturn(result);
// Updated mock (if parameter added)
when(service.process(data, context)).thenReturn(result);
// Or use argument matchers
when(service.process(eq(data), any(Context.class))).thenReturn(result);For changed mock behavior:
// Old mock (method returned boolean)
when(validator.isValid(input)).thenReturn(true);
// Updated mock (method now throws exception instead)
doNothing().when(validator).validate(input);
// Or for invalid case:
doThrow(new ValidationException()).when(validator).validate(invalidInput);Create additional tests for new functionality or edge cases:
For new parameters:
@Test
public void testCalculateDiscountWithZeroRate() {
double result = calculator.calculateDiscount(100.0, 0.0);
assertEquals(0.0, result, 0.01);
}
@Test
public void testCalculateDiscountWithMaxRate() {
double result = calculator.calculateDiscount(100.0, 1.0);
assertEquals(100.0, result, 0.01);
}For new exceptions:
@Test
public void testNegativeDiscountRate() {
assertThrows(IllegalArgumentException.class, () -> {
calculator.calculateDiscount(100.0, -0.5);
});
}
@Test
public void testDiscountRateAboveOne() {
assertThrows(IllegalArgumentException.class, () -> {
calculator.calculateDiscount(100.0, 1.5);
});
}For new behavior:
@Test
public void testNewFeature() {
// Test newly added functionality
Result result = service.newMethod(input);
assertNotNull(result);
assertEquals(expectedValue, result.getValue());
}Modify test fixtures if dependencies changed:
For constructor changes:
// Old setup
@BeforeEach
void setUp() {
calculator = new Calculator();
}
// Updated setup (if constructor now requires dependencies)
@BeforeEach
void setUp() {
validator = new Validator();
calculator = new Calculator(validator);
}For new dependencies:
// Old setup
@Mock
private Repository repository;
// Updated setup (if new dependency added)
@Mock
private Repository repository;
@Mock
private CacheService cacheService;
@BeforeEach
void setUp() {
service = new Service(repository, cacheService);
}Ensure updated tests compile without errors:
Check for compilation issues:
Common compilation fixes:
// Add missing imports
import java.util.Optional;
import static org.mockito.ArgumentMatchers.any;
// Fix type mismatches
Long userId = 123L; // Instead of int userId = 123;
// Update generic types
List<String> items = new ArrayList<>(); // Instead of raw ListCompile tests:
# Maven
mvn test-compile
# Gradle
./gradlew testClassesExecute tests to ensure they pass:
Run all updated tests:
# Maven
mvn test -Dtest=CalculatorTest
# Gradle
./gradlew test --tests CalculatorTestAnalyze test results:
If tests fail:
Ensure updated tests maintain quality standards:
Check test coverage:
Verify test independence:
Review test clarity:
Old code:
public String formatName(String firstName, String lastName) {
return firstName + " " + lastName;
}New code:
public String formatName(String firstName, String lastName, String title) {
return title + " " + firstName + " " + lastName;
}Old test:
@Test
public void testFormatName() {
String result = formatter.formatName("John", "Doe");
assertEquals("John Doe", result);
}Updated test:
@Test
public void testFormatName() {
String result = formatter.formatName("John", "Doe", "Mr.");
assertEquals("Mr. John Doe", result);
}
@Test
public void testFormatNameWithEmptyTitle() {
String result = formatter.formatName("John", "Doe", "");
assertEquals(" John Doe", result);
}Old code:
public class UserService {
public boolean validateEmail(String email) {
return email.contains("@");
}
}New code:
public class UserService {
private EmailValidator validator;
// validateEmail moved to EmailValidator
}
public class EmailValidator {
public boolean isValid(String email) {
return email.contains("@");
}
}Old test:
@Test
public void testValidateEmail() {
assertTrue(userService.validateEmail("user@example.com"));
}Updated test:
@Mock
private EmailValidator emailValidator;
@BeforeEach
void setUp() {
userService = new UserService(emailValidator);
}
@Test
public void testEmailValidation() {
when(emailValidator.isValid("user@example.com")).thenReturn(true);
// Test userService method that uses emailValidator
}
// Or create separate test for EmailValidator
@Test
public void testEmailValidatorIsValid() {
EmailValidator validator = new EmailValidator();
assertTrue(validator.isValid("user@example.com"));
}Old code:
public User findUser(Long id) {
return repository.findById(id); // Returns User or null
}New code:
public Optional<User> findUser(Long id) {
return repository.findById(id); // Returns Optional<User>
}Old test:
@Test
public void testFindUser() {
User user = service.findUser(123L);
assertNotNull(user);
assertEquals("John", user.getName());
}Updated test:
@Test
public void testFindUser() {
Optional<User> userOpt = service.findUser(123L);
assertTrue(userOpt.isPresent());
assertEquals("John", userOpt.get().getName());
}
@Test
public void testFindUserNotFound() {
Optional<User> userOpt = service.findUser(999L);
assertFalse(userOpt.isPresent());
}0f00a4f
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.