Using ChatGPT to Refine Java Unit Tests – Episode 23

This article walks through adjusting Java unit tests with ChatGPT, measuring coverage using JaCoCo, rewriting test code for User and PasswordRecovery classes, adding Mockito and PowerMock mocks, and showing how the changes raise coverage from 73.7% to over 80% across the project.

Woodpecker Software Testing
Woodpecker Software Testing
Woodpecker Software Testing
Using ChatGPT to Refine Java Unit Tests – Episode 23

Initial coverage

JaCoCo run after debugging shows overall product coverage 87.3 %. ValidateUser.java 100 %, User.java 34.1 %, PasswordRecovery.java 50.5 %.

Step 1 – Adjust SendSms.java

Comment out debug statements.

Replace catch blocks with a simplified version that logs the error via logger.error(e.getMessage()) and returns false.

Step 2 – Regenerate UserTest.java

Prompt to ChatGPT: “Generate unit‑test cases for the code below.” Resulting JUnit 5 test class includes:

package ebusiness;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class UserTest {
    private User user;
    @BeforeEach
    public void setUp() {
        user = new User("testUser", "password123");
    }
    @Test public void testUsernameValid() { assertEquals("testUser", user.getUsername()); }
    @Test public void testPasswordValid() { assertEquals("password123", user.getPassword()); }
    @Test public void testPhoneDefault() { assertEquals("13611223344", user.getPhone()); }
    @Test public void testEmailDefault() { assertEquals("[email protected]", user.getEmail()); }
    @Test public void testSetUsernameValid() { user.setUsername("newUser"); assertEquals("newUser", user.getUsername()); }
    @Test public void testSetUsernameInvalid() {
        Exception e = assertThrows(IllegalArgumentException.class, () -> user.setUsername(""));
        assertEquals("无效的用户账号", e.getMessage());
        assertThrows(IllegalArgumentException.class, () -> user.setUsername("abc"));
        assertThrows(IllegalArgumentException.class, () -> user.setUsername(null));
    }
    // Additional tests for password, phone, email setters and constructors omitted for brevity
}

Uses @BeforeEach to create a fresh User instance for each test, includes normal‑case and exception‑case assertions, and replaces plain assertXXX calls with Assertions.assertXXX. The test suite runs successfully.

Step 3 – Adjust PasswordRecoveryTest.java

Add Maven dependency powermock-reflect version 2.0.9 to pom.xml:

<dependency>
  <groupId>org.powermock</groupId>
  <artifactId>powermock-reflect</artifactId>
  <version>2.0.9</version>
  <scope>test</scope>
</dependency>

Test class employs JUnit 5, Mockito, PowerMock, and Whitebox to mock static utilities and external services:

package ebusiness;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.*;
import org.mockito.junit.jupiter.MockitoExtension;
import org.powermock.reflect.Whitebox;
import demo.SendSms;

@ExtendWith(MockitoExtension.class)
class PasswordRecoveryTest {
    @Mock private Util mockUtil;
    @Mock private SendSms mockSendSms;
    @InjectMocks private PasswordRecovery passwordRecovery;
    @Mock private UserRepository userRepository;

    @BeforeEach void setUp() throws SQLException {
        passwordRecovery = new PasswordRecovery();
        Whitebox.setInternalState(passwordRecovery, "util", mockUtil);
    }

    @Test void testSendVerificationCode_InvalidContact() throws Exception {
        String result = passwordRecovery.sendVerificationCode("invalid_contact");
        Assertions.assertEquals("您输入的手机号或Email格式不正确!", result);
    }

    @Test void testRecoverPassword_Success() throws SQLException {
        // arrange mocks for verifyCode, getPassword, storeOldPassword, updatePassword, verifyPassword
        String result = passwordRecovery.recoverPassword("123456", newHashed, userRepository, 123);
        Assertions.assertEquals("0", result);
    }
    // Additional tests for password‑used, old‑password error, SQLException, contact‑type detection, SMS/Email success, etc.
}

Coverage improvement

SendSms.java: 65.2 % → 88.7 %

User.java: 34.1 % → 97.6 %

PasswordRecovery.java: 50.5 % → 79.7 %

Overall product code: 73.7 % → 81.5 %

Unit‑test count analysis

Table 4‑2 (referenced image) lists the number of unit tests per class and the percentage of code exercised.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Javacode coverageChatGPTunit testingJUnitMockitoJaCoCo
Woodpecker Software Testing
Written by

Woodpecker Software Testing

The Woodpecker Software Testing public account shares software testing knowledge, connects testing enthusiasts, founded by Gu Xiang, website: www.3testing.com. Author of five books, including "Mastering JMeter Through Case Studies".

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.