JUnit测试中@Value注入aws.s3.bucketName值为Null的解决求助
解决JUnit测试中@Value注入属性为Null的问题
你遇到的问题根源是:使用MockitoExtension时,Spring容器并未启动,Mockito的@InjectMocks只会注入标注了@Mock的Bean,不会处理@Value注解的属性注入,导致bucketName为null。以下是三种直接可行的解决方法:
方法一:反射直接设置属性值(最适合单元测试)
用Spring Test提供的ReflectionTestUtils工具,直接给私有字段赋值,无需修改被测试类代码:
@ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) public class AsyncPublisherServiceImplTest { @InjectMocks private AsyncPublisherServiceImpl asyncPublisherServiceImpl; @Mock private AsyncPublisherDao dao; @Mock private AsyncUtil asyncUtil; @Mock private ClientListenerService techpulseservice; @BeforeEach void setUp() { // 直接给bucketName赋值 ReflectionTestUtils.setField(asyncPublisherServiceImpl, "bucketName", "hpmap-pro-development-os-asyncmulti"); } @Test void publish() { String link = null; PublisherRequest PublisherRequest = RequestUtils.getPublisherRequest(); lenient().when(dao.isValidCount(ConstantsTest.UUID)).thenReturn(true); File file = new File(AsyncUtil.sanitizePathandfilename(ConstantsTest.UUID + ".zip")); assertNotNull(asyncPublisherServiceImpl.publish(PublisherRequest.getUuid(), ConstantsTest.UnitOfWorkId)); } }
方法二:启动Spring上下文加载配置(适合集成测试)
如果需要加载真实的配置文件,用@SpringBootTest启动Spring容器,让Spring自动处理@Value注入:
@SpringBootTest @MockitoSettings(strictness = Strictness.LENIENT) public class AsyncPublisherServiceImplTest { @Autowired private AsyncPublisherServiceImpl asyncPublisherServiceImpl; @MockBean private AsyncPublisherDao dao; @MockBean private AsyncUtil asyncUtil; @MockBean private ClientListenerService techpulseservice; @Test void publish() { String link = null; PublisherRequest PublisherRequest = RequestUtils.getPublisherRequest(); lenient().when(dao.isValidCount(ConstantsTest.UUID)).thenReturn(true); File file = new File(AsyncUtil.sanitizePathandfilename(ConstantsTest.UUID + ".zip")); assertNotNull(asyncPublisherServiceImpl.publish(PublisherRequest.getUuid(), ConstantsTest.UnitOfWorkId)); } }
注意:这里用@MockBean替代@Mock,目的是将Mock对象注入到Spring容器中。
方法三:重构代码,用配置类替代直接@Value(推荐长期方案)
将配置属性封装到配置类中,通过构造注入传入被测试类,提升代码可测试性:
1. 创建S3配置类
@Configuration @ConfigurationProperties(prefix = "aws.s3") public class S3Config { private String bucketName; private String region; // getter、setter public String getBucketName() { return bucketName; } public void setBucketName(String bucketName) { this.bucketName = bucketName; } public String getRegion() { return region; } public void setRegion(String region) { this.region = region; } }
2. 修改被测试类为构造注入
@Service @Transactional public class AsyncPublisherServiceImpl implements AsyncPublisherService { Logger logger = LoggerFactory.getLogger(this.getClass().getName()); private final AsyncPublisherDao dao; private final AsyncUtil asyncUtil; private final ClientListenerService techpulseservice; private final String bucketName; // 构造注入替代@Autowired和@Value public AsyncPublisherServiceImpl(AsyncPublisherDao dao, AsyncUtil asyncUtil, ClientListenerService techpulseservice, S3Config s3Config) { this.dao = dao; this.asyncUtil = asyncUtil; this.techpulseservice = techpulseservice; this.bucketName = s3Config.getBucketName(); } // 原有业务逻辑代码不变 }
3. 测试类直接传入配置实例
@ExtendWith(MockitoExtension.class) @MockitoSettings(strictness = Strictness.LENIENT) public class AsyncPublisherServiceImplTest { private AsyncPublisherServiceImpl asyncPublisherServiceImpl; @Mock private AsyncPublisherDao dao; @Mock private AsyncUtil asyncUtil; @Mock private ClientListenerService techpulseservice; @BeforeEach void setUp() { S3Config s3Config = new S3Config(); s3Config.setBucketName("hpmap-pro-development-os-asyncmulti"); // 直接通过构造方法传入所需依赖 asyncPublisherServiceImpl = new AsyncPublisherServiceImpl(dao, asyncUtil, techpulseservice, s3Config); } @Test void publish() { String link = null; PublisherRequest PublisherRequest = RequestUtils.getPublisherRequest(); lenient().when(dao.isValidCount(ConstantsTest.UUID)).thenReturn(true); File file = new File(AsyncUtil.sanitizePathandfilename(ConstantsTest.UUID + ".zip")); assertNotNull(asyncPublisherServiceImpl.publish(PublisherRequest.getUuid(), ConstantsTest.UnitOfWorkId)); } }
内容的提问来源于stack exchange,提问作者S.R.D
相关产品推荐
相关产品推荐

