测试创建SendMail对象的私有void方法时触发空指针异常排查
sendActivationCode method despite PowerMockito stub Hey there, let's break down what's happening here. The NullPointerException isn't directly caused by not mocking SendMail—the real issue is that your PowerMockito stub for the private sendActivationCode method isn't working correctly, so the actual method logic is still executing, and something inside that logic is null.
Let's walk through this step by step:
1. Why your stub isn't stopping the method execution
Your test code uses PowerMockito.doNothing().when(profileNotificationBOSpy, "sendActivationCode", Mockito.any(MailInfoDTO.class)); to stub the private method, but this setup might be incomplete:
- Make sure your test class is annotated with
@RunWith(PowerMockRunner.class)and@PrepareForTest(ProfileNotificationBO.class)—PowerMockito needs these to manipulate the spy and private methods properly. - If the stub isn't applied correctly, the real
sendActivationCodelogic runs, leading to the NPE you're seeing.
2. What's causing the NPE
Looking at your stack trace, the NPE occurs at line 778 of ProfileNotificationBO.java inside sendActivationCode. Let's check the likely culprits in your method code:
PropertiesHelper.getPropertyreturning null: If calls likePropertiesHelper.getProperty("smtp_server")return null, passing that tosm.setMailHost()could trigger an NPE later whensendSMTP()runs.MailInfoDTOproperties being null: IfmailInfoBn.getMailTo()or other getters return null, setting those values onSendMailmight cause issues in subsequent method calls.- Unmocked
SendMailbehavior: Even if you create a realSendMailinstance, itssendSMTP()method might throw an NPE if required fields are left null.
3. Fixes you can apply
Option 1: Get the stub working properly
Ensure your test class has the necessary annotations, and verify the stub is applied before invoking the method that triggers sendActivationCode. This will skip executing the method's logic entirely:
@RunWith(PowerMockRunner.class) @PrepareForTest(ProfileNotificationBO.class) public class TestProfileNotificationBO { @Test public void testGenerateActivationCodeWhenMblNotRegistered() throws Exception { ProfileNotificationBO profileNotificationBO = new ProfileNotificationBO(); ProfileNotificationBO profileNotificationBOSpy = PowerMockito.spy(profileNotificationBO); // Stub the private method to do nothing PowerMockito.doNothing().when(profileNotificationBOSpy, "sendActivationCode", Mockito.any(MailInfoDTO.class)); // Invoke the public method that calls sendActivationCode here // ... } }
Option 2: Mock all dependencies inside the private method
If you need to verify behavior (instead of just skipping the method), mock every dependency used in sendActivationCode:
- Mock
PropertiesHelperto return valid configuration values:PowerMockito.mockStatic(PropertiesHelper.class); PowerMockito.when(PropertiesHelper.getProperty("smtp_server")).thenReturn("smtp.yourdomain.com"); PowerMockito.when(PropertiesHelper.getProperty("smtp_auth_user")).thenReturn("auth-user"); PowerMockito.when(PropertiesHelper.getProperty("smtp_auth_pass")).thenReturn("auth-pass"); - Mock the
SendMailconstructor to return a mock instance (so the realsendSMTP()isn't called):SendMail mockSendMail = Mockito.mock(SendMail.class); PowerMockito.whenNew(SendMail.class).withNoArguments().thenReturn(mockSendMail); - Mock
MailInfoDTOto return valid email details:MailInfoDTO mockMailInfo = Mockito.mock(MailInfoDTO.class); Mockito.when(mockMailInfo.getMailTo()).thenReturn("user@example.com"); Mockito.when(mockMailInfo.getMailFrom()).thenReturn("noreply@yourdomain.com"); // Mock other required getters...
4. Verify the NPE location
Double-check line 778 in ProfileNotificationBO.java to pinpoint exactly what's null. That will let you target your mocks more precisely and fix the issue faster.
内容的提问来源于stack exchange,提问作者Arnab

