Значение Environment getProperty (SomeValue) становится нулевым с тестом Spring и Mockito

Я пишу JUnits для классов контроллеров. Я использую объекты @PropertySource("classpath:webmvc_test.properties") и Environment для чтения значений из файла свойств. При вызове метода getProperty() получение значения null. Файл свойств webmvc_test.properties находится в пути к классу.

TestClass.java:

package com.kalavakuri.webmvc.web.controller;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import com.kalavakuri.webmvc.business.service.FamilyService;
import com.kalavakuri.webmvc.business.valueobject.FamilyAddress;
import com.kalavakuri.webmvc.business.valueobject.FamilyVO;
import com.kalavakuri.webmvc.init.ApplicationInitializer;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ApplicationInitializer.class })
@PropertySource("classpath:webmvc_test.properties")
public class WelcomeControllerTest {

    @Mock
    private FamilyService familyService;

    @InjectMocks
    private WelcomeController welcomeController;

    @Autowired
    private Environment environment;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(welcomeController).build();
    }

    @Test
    public void welcomePage() throws Exception {

        FamilyVO allFamilyMembers = getAllFamilyMembers();

        when(familyService.getAllFamilyMembers()).thenReturn(allFamilyMembers);
        mockMvc.perform(get("/")).andExpect(status().isOk()).andExpect(view().name("Index"));
    }

    /**
     * @return
     */
    private FamilyVO getAllFamilyMembers() {
        FamilyVO allFamilyMembers = new FamilyVO();
        FamilyVO familyVO = new FamilyVO();
        familyVO.setFamilyId(Integer.parseInt(environment.getProperty("familyId")));
        familyVO.setFamilyMemberName(environment.getProperty("familyMemberName"));
        familyVO.setFamilyMemberAge(Integer.parseInt(environment.getProperty("familyMemberAge")));

        FamilyAddress familyAddress = new FamilyAddress();
        familyAddress.setAddress(environment.getProperty("familyAddress"));
        familyVO.setFamilyAddress(familyAddress);

        List<FamilyVO> familyVOs = new ArrayList<FamilyVO>();
        familyVOs.add(familyVO);

        allFamilyMembers.setFamilyVOs(familyVOs);
        return allFamilyMembers;
    }
}


webmvc_test.properties:

familyId=1
familyMemberName=Ramachandrappa Kalavakuri
familyMemberAge=36
familyAddress=Flat no: 305, 2nd Floor, Prakasa Pride Apartments, Opp To J.P.Morgan, Kadubesinahalli, Bangalore - 560087

person user995656    schedule 16.05.2019    source источник
comment
как ты провел тест? возможные ресурсы не были представлены в classpath   -  person borino    schedule 16.05.2019
comment
Я упомянул, что webmvc_test.properties - это путь к классам - он находится в src/test/resources.   -  person user995656    schedule 16.05.2019
comment
Просто чтобы быть уверенным, что если ваш файл находится в правильном месте в IDE, это не означает 100%, что во время выполнения он присутствует в пути к классам, потому что это зависит от того, как вы запускаете свои тесты.   -  person borino    schedule 17.05.2019


Ответы (1)


У меня была та же проблема, и когда я искал ее решение, я нашел эту статью @Autowired + PowerMock : исправление некоторых неправильных/злоупотреблений Spring Framework кажется, что существует проблема проектирования между powermock и spring, которая препятствует правильной работе @Autowire внутри тестовых классов, поэтому вместо использования @Autowire используйте @Mock и ожидайте возвращаемых значений.

package com.kalavakuri.webmvc.web.controller;

import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;

import java.util.ArrayList;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import com.kalavakuri.webmvc.business.service.FamilyService;
import com.kalavakuri.webmvc.business.valueobject.FamilyAddress;
import com.kalavakuri.webmvc.business.valueobject.FamilyVO;
import com.kalavakuri.webmvc.init.ApplicationInitializer;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { ApplicationInitializer.class })
@PropertySource("classpath:webmvc_test.properties")
public class WelcomeControllerTest {

    @Mock
    private FamilyService familyService;

    @InjectMocks
    private WelcomeController welcomeController;

    @Mock
    private Environment environment;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(welcomeController).build();

        when(environment.getProperty("familyId")).thenReturn("1");
        when(environment.getProperty("familyMemberName")).thenReturn("Ramachandrappa Kalavakuri");
        when(environment.getProperty("familyMemberAge")).thenReturn("36");
        when(environment.getProperty("familyAddress")).thenReturn("Flat no: 305, 2nd Floor, Prakasa Pride Apartments, Opp To J.P.Morgan, Kadubesinahalli, Bangalore - 560087"); 
    }

    @Test
    public void welcomePage() throws Exception {

        FamilyVO allFamilyMembers = getAllFamilyMembers();

        when(familyService.getAllFamilyMembers()).thenReturn(allFamilyMembers);
        mockMvc.perform(get("/")).andExpect(status().isOk()).andExpect(view().name("Index"));
    }

    /**
     * @return
     */
    private FamilyVO getAllFamilyMembers() {
        FamilyVO allFamilyMembers = new FamilyVO();
        FamilyVO familyVO = new FamilyVO();
        familyVO.setFamilyId(Integer.parseInt(environment.getProperty("familyId")));
        familyVO.setFamilyMemberName(environment.getProperty("familyMemberName"));
        familyVO.setFamilyMemberAge(Integer.parseInt(environment.getProperty("familyMemberAge")));

        FamilyAddress familyAddress = new FamilyAddress();
        familyAddress.setAddress(environment.getProperty("familyAddress"));
        familyVO.setFamilyAddress(familyAddress);

        List<FamilyVO> familyVOs = new ArrayList<FamilyVO>();
        familyVOs.add(familyVO);

        allFamilyMembers.setFamilyVOs(familyVOs);
        return allFamilyMembers;
    }
}
person Amgad Hanafy    schedule 30.10.2019