@TestPropertySource无法帮助获取配置属性值

时间:2020-01-29 18:56:06

标签: spring-boot mockito junit5

在以下测试代码片段中,未从配置文件中获取number_of_days.last和number_of_months.plan的值。请检查并查看原因是什么。当我从服务类ShiftPlanService中删除@Value注释时。 Java,然后使用所需的值初始化那里的值,测试通过。

@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;

3 个答案:

答案 0 :(得分:0)

我认为您打算使用ShiftPlanService的真实实例并注入了模拟。您需要让Spring自动将ShiftPlanService连接到您的测试中,并告诉它像这样注入模拟:

@Autowired
@InjectMocks
ShiftPlanService sps;

尽管您可能会考虑只在自己的设置方法中实例化ShiftPlanService,然后传递模拟并在ShiftPlanService上设置其他属性。

答案 1 :(得分:0)

您将Mockito注入与Spring注入混淆了。 @Value是Spring的概念,只有在Spring管理bean时才会注入,但是您在测试中拥有的ShiftPlanService的实例是由Mockito使用@Spy注入的(正如已经指出的那样,您并不需要)。

我的建议是确定所需的内容-使用模拟的单元测试,或运行应用程序上下文的成熟的Spring测试。在我看来,您的意图是编写一个模拟了所有内容的单元测试,在这种情况下:

  • 删除@ContextConfiguration@TestPropertySource(对于单元测试,您不需要这些)
  • @InjectMocks上使用@Spy而不是ShiftPlanService sps-取决于实现ShiftPlanService的方式,它很可能会做您想做的事
  • sps中手动设置所需的配置值;您可以添加供测试使用的设置器;如果单元测试与该类位于同一软件包中(这是一个好习惯,那么它们也可以是私有的),因为在生产中,Spring会自动为您布线,因此您只需要它们进行测试
  • 哦,将@Value批注保留在ShiftPlanService中-这是生产所必需的-如上文所述

答案 2 :(得分:0)

我们发明了一个Mockito扩展,可以轻松注入String / Integer / Boolean属性。查看自述文件,它非常易于使用,并且可以与@InjectMocks

一起使用

https://github.com/exabrial/mockito-object-injection