Spring boot @TestPropertySource无法帮助获取配置属性值
在下面的测试代码片段中,未从配置文件中获取number_of_days.last和number_of_months.plan的值。请检查原因。当我从服务类ShiftPlanService.java中删除@Value annotation并使用所需值初始化其中的值时,考试通过了Spring boot @TestPropertySource无法帮助获取配置属性值,spring-boot,mockito,junit5,Spring Boot,Mockito,Junit5,在下面的测试代码片段中,未从配置文件中获取number_of_days.last和number_of_months.plan的值。请检查原因。当我从服务类ShiftPlanService.java中删除@Value annotation并使用所需值初始化其中的值时,考试通过了 @ExtendWith(MockitoExtension.class) @ContextConfiguration(classes=SpringbootMysqlExampleApplication.class) @Tes
@ExtendWith(MockitoExtension.class)
@ContextConfiguration(classes=SpringbootMysqlExampleApplication.class)
@TestPropertySource(locations="src/main/resources/application.properties",properties= {"number_of_days.last= 7","number_of_months.plan= 2"})
class ShiftPlanServiceTest {
@Mock
ShiftPlanRepo mockedSpr;
@Mock(lenient = true)
ShiftDetailsRepo mockedSdr;
@Mock(lenient = true)
EmployeeDetailsRepo mockedEdr;
@Spy
ShiftPlanService sps;
@BeforeEach
public void setUp() {
when(mockedSdr.findShiftNameById(1)).thenReturn("Morning");
when(mockedSdr.findShiftNameById(2)).thenReturn("Afternoon");
when(mockedEdr.getNameById(0)).thenReturn("Amit");
when(mockedEdr.getNameById(1)).thenReturn("Anupam");
when(mockedEdr.getNameById(2)).thenReturn("Chirag");
when(mockedEdr.getNameById(3)).thenReturn("Rashmi");
when(mockedEdr.count()).thenReturn(4L);
}
@Test
public void testCreateShiftPlan() {
sps.createShiftPlan(4, 1, 2020);
verify(mockedSpr, times(36)).save(any(ShiftPlan.class));
verifyNoMoreInteractions(mockedSpr);
}
}
application.properties文件如下所示-
server.port=8104
number_of_days.last= 7
number_of_months.plan= 2
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/shiftplannerdatabase
spring.datasource.username=root
spring.datasource.password=WILLsuc95#
#Keep the connection alive while idle for a long time
spring.datasource.testWhileIdle= true
spring.datasource.validationQuery= SELECT 1
# Show or not log for each sql query
spring.jpa.show-sql = true
# Hibernate ddl auto (create, create-drop, update)
spring.jpa.hibernate.ddl-auto = update
# Naming strategy
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
# Use spring.jpa.properties.* for Hibernate native properties (the prefix is
# stripped before adding them to the entity manager)
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
在ShiftPlanService类中,我有
@Value("${number_of_days.last}")
public int ndl;
@Value("${number_of_months.plan}")
public int nm;
我认为您打算使用ShiftPlanService的一个真实实例,并注入模拟。您需要让Spring自动将ShiftPlance连接到您的测试中,并告诉它以如下方式注入模拟:
@Autowired
@InjectMocks
ShiftPlanService sps;
尽管您可以考虑只在Sebug方法中实例化SHIVTFraseService,而只是传递您的模拟,并在SefftPrimeService上设置其他属性。p> 我认为您打算使用ShiftPlanService的一个真实实例并注入模拟。您需要让Spring自动将ShiftPlance连接到您的测试中,并告诉它以如下方式注入模拟:
@Autowired
@InjectMocks
ShiftPlanService sps;
尽管您可以考虑只在Sebug方法中实例化SHIVTFraseService,而只是传递您的模拟,并在SefftPrimeService上设置其他属性。p> 您混淆了Mockito注入和Spring注入
@Value
是Spring的概念,只有在Spring管理bean时才会被注入,但是您在测试中拥有的ShiftPlanService
的实例是由Mockito
使用@Spy
注入的(正如已经指出的,您实际上并不需要)
我的建议是决定您想要什么——使用mock进行单元测试,或者运行应用程序上下文的完整Spring测试。在我看来,您的意图是编写一个单元测试,并模拟所有内容,在这种情况下:
- 删除
和@ContextConfiguration
(单元测试不需要这些)@TestPropertySource
- 在
上使用ShiftPlanService sps
而不是@InjectMocks
——它很可能会执行您想要的操作,具体取决于@Spy
的实现方式ShiftPlanService
- 在
中手动设置所需的配置值;您可以为要使用的测试添加设置器;如果单元测试与类在同一个包中——这是一个很好的实践——它们也可以是包私有的——因为在生产环境中,Spring会为您自动连接它们,所以您只需要在测试中使用它们sps
- 哦,将
注释保留在@Value
中-这是生产所需的-如上所述ShiftPlanService
@Value
是Spring的概念,只有在Spring管理bean时才会被注入,但是您在测试中拥有的ShiftPlanService
的实例是由Mockito
使用@Spy
注入的(正如已经指出的,您实际上并不需要)
我的建议是决定您想要什么——使用mock进行单元测试,或者运行应用程序上下文的完整Spring测试。在我看来,您的意图是编写一个单元测试,并模拟所有内容,在这种情况下:
- 删除
和@ContextConfiguration
(单元测试不需要这些)@TestPropertySource
- 在
上使用ShiftPlanService sps
而不是@InjectMocks
——它很可能会执行您想要的操作,具体取决于@Spy
的实现方式ShiftPlanService
- 在
中手动设置所需的配置值;您可以为要使用的测试添加设置器;如果单元测试与类在同一个包中——这是一个很好的实践——它们也可以是包私有的——因为在生产环境中,Spring会为您自动连接它们,所以您只需要在测试中使用它们sps
- 哦,将
注释保留在@Value
中-这是生产所需的-如上所述ShiftPlanService
@InjectMocks
我们发明了一个Mockito扩展,它允许轻松地注入字符串/整数/布尔属性。查看自述文件,它非常易于使用,并且与
@InjectMocks
Hi,@SpyBean ShiftPlanService sps;没用。在执行该操作之后,我在sps.createShiftPlan(4,1,2020)行收到空指针异常;我重读了你的问题,我认为这个问题与Spring有关,而不是与mock中的自动布线有关。您不需要为此使用间谍,因为您没有对ShiftPlanService进行任何间谍活动。您好,@SpyBean ShiftPlanService sps;没用。在执行该操作之后,我在sps.createShiftPlan(4,1,2020)行收到空指针异常;我重读了你的问题,我认为这个问题与Spring有关,而不是与mock中的自动布线有关。你不应该为此使用间谍,因为你没有对ShiftPlanService进行任何间谍活动。我应该在哪里添加这些setter,在test类中还是在ShiftPlanService类中?2.在同一个包中意味着如果ShiftPlanService在src/main/java/com.example.springboot.shift.planner.service中,而测试类在src/test/java/com.example.springboot.shift.planner.service中,那么它们是否在同一个包中?(1)在
ShitfPlanService
中,并在测试中调用它们来设置测试中需要的值(2)是,这是(IMO)单元测试的一个良好实践(组件/集成测试,其中启动Spring是一个单独的测试类,通常位于单独的包甚至模块中)。好处是你很容易知道去哪里