You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何测试抛出IllegalStateException的Java私有构造方法?

Testing a Private Constructor That Throws IllegalStateException

Great question! Your current test works fine when the constructor doesn’t throw an exception, but we need to adjust it to verify that the expected IllegalStateException is actually being thrown when the private constructor is invoked. Here are two straightforward approaches based on your JUnit version:

JUnit 5’s assertThrows method is clean and direct—it lets you execute the code that should throw an exception, and verifies the exception type (and even its message) in one step.

Here’s how to modify your test:

@Test
public void privateConstructor_ThrowsIllegalStateException() throws Exception {
    // Retrieve the private constructor
    Constructor<DetailRecord> constructor = DetailRecord.class.getDeclaredConstructor();
    
    // Verify the constructor is indeed private
    assertTrue(Modifier.isPrivate(constructor.getModifiers()));
    
    // Make the constructor accessible
    constructor.setAccessible(true);
    
    // Assert that invoking the constructor throws the expected exception
    IllegalStateException thrownException = assertThrows(
        IllegalStateException.class,
        constructor::newInstance // Lambda to call the constructor
    );
    
    // Optional: Verify the exception message matches your expected value
    assertEquals(ExceptionCodes.FACTORY_CLASS.getMessage(), thrownException.getMessage());
}

How this works:

  • assertThrows executes the lambda (constructor::newInstance) and catches any exception thrown.
  • If the exception is of type IllegalStateException, the test passes; if no exception is thrown, or the wrong type is thrown, the test fails.
  • The optional assertEquals step confirms the exception message is exactly what you defined, adding an extra layer of validation for your business logic.

Option 2: Using JUnit 4 (For Legacy Projects)

If you’re still using JUnit 4, you can use the ExpectedException rule to declare the exception you expect before invoking the constructor.

Here’s the modified test:

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;

public class DetailRecordTest {

    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    @Test
    public void privateConstructor_ThrowsIllegalStateException() throws Exception {
        Constructor<DetailRecord> constructor = DetailRecord.class.getDeclaredConstructor();
        
        assertTrue(Modifier.isPrivate(constructor.getModifiers()));
        constructor.setAccessible(true);
        
        // Declare the expected exception type
        expectedException.expect(IllegalStateException.class);
        // Declare the expected exception message
        expectedException.expectMessage(ExceptionCodes.FACTORY_CLASS.getMessage());
        
        // Invoke the constructor—this will throw the exception, which the rule will catch
        constructor.newInstance();
    }
}

How this works:

  • The @Rule annotation sets up ExpectedException to monitor the test method.
  • We first tell the rule what exception type and message we expect.
  • When we call constructor.newInstance(), the exception is thrown and caught by the rule. If it matches our expectations, the test passes.

Key Takeaway

Both approaches focus on two critical checks:

  1. Confirming the constructor is private (your original check, which we keep).
  2. Verifying that invoking the constructor throws the exact IllegalStateException (with the correct message, if needed) that your implementation defines.

内容的提问来源于stack exchange,提问作者Santiago Molano

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:05:08