복붙노트

[SPRING] 테스트 케이스로부터 제어기를 호출 할 때 자동 유선 컴포넌트와 제어기를 테스트하면 널

SPRING

테스트 케이스로부터 제어기를 호출 할 때 자동 유선 컴포넌트와 제어기를 테스트하면 널

나는 컨트롤러가

@RestController
public class Create {

    @Autowired
    private ComponentThatDoesSomething something;

    @RequestMapping("/greeting")
    public String call() {
        something.updateCounter();
        return "Hello World " + something.getCounter();
    }

}

그 컨트롤러의 구성 요소가

@Component
public class ComponentThatDoesSomething {
    private int counter = 0;

    public void updateCounter () {
        counter++;
    }

    public int getCounter() {
        return counter;
    }
}

나는 또한 내 컨트롤러에 대한 테스트가 있습니다.

@RunWith(SpringRunner.class)
@SpringBootTest
public class ForumsApplicationTests {

    @Test
    public void contextLoads() {
        Create subject = new Create();
        subject.call();
        subject.call();
        assertEquals(subject.call(), "Hello World 2");
    }

}

컨트롤러가 something.updateCounter를 호출 할 때 테스트가 실패 (). 나는 NullPointerException이 얻을. 나는 그것이 생성자에 @Autowired를 추가 할 수있어 이해하면서 @Autowired 필드와 함께이 일을 어쨌든이 있는지 알고 싶습니다. 어떻게 내 테스트에서 @Autowired 필드 주석 작동하는지 확인합니까?

해결법

  1. ==============================

    1.구성 요소 instatntiated되지 않도록 당신이, 봄하지 새와 컨트롤러의 인스턴스를 원인 봄하지 자동 와이어 구성 요소를 않습니다

    구성 요소 instatntiated되지 않도록 당신이, 봄하지 새와 컨트롤러의 인스턴스를 원인 봄하지 자동 와이어 구성 요소를 않습니다

    봄 MockMvc 테스트는 정확한 확인 :

    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringBootTest
    public class CreateTest {
        @Autowired
        private WebApplicationContext context;
    
        private MockMvc mvc;
    
        @Before
        public void setup() {
            mvc = MockMvcBuilders
                    .webAppContextSetup(context)
                    .build();
        }
    
        @Test
        public void testCall() throws Exception {
            //increment first time
            this.mvc.perform(get("/greeting"))
                    .andExpect(status().isOk());
            //increment secont time and get response to check
            String contentAsString = this.mvc.perform(get("/greeting"))
                    .andExpect(status().isOk()).andReturn()
                    .getResponse().getContentAsString();
            assertEquals("Hello World 2", contentAsString);
        }
    }
    
  2. ==============================

    2.Mockito를 사용하여 사용자가 만든 모의를 주입. 나는 생성자 주입을 선호 할 것입니다 :

    Mockito를 사용하여 사용자가 만든 모의를 주입. 나는 생성자 주입을 선호 할 것입니다 :

    @RestController
    public class Create {
    
        private ComponentThatDoesSomething something;
    
        @Autowired
        public Create(ComponentThatDoesSomething c) {
            this.something = c;
        }
    }
    

    당신의 JUnit 테스트에 스프링을 사용하지 마십시오.

    public CreateTest {
    
        private Create create;
    
        @Before
        public void setUp() {
            ComponentThatDoesSomething c = Mockito.mock(ComponentThatDoesSomething .class);
            this.create = new Create(c);
        } 
    }
    
  3. ==============================

    3.@Autowired 클래스는 쉽게 조롱하고 올바른 주석과 MockitoJUnitRunner으로 테스트 할 수 있습니다.

    @Autowired 클래스는 쉽게 조롱하고 올바른 주석과 MockitoJUnitRunner으로 테스트 할 수 있습니다.

    이것으로 당신은 단위 테스트를위한 모의 객체로 할 필요가 무엇이든 할 수 있습니다.

    여기 ComponentThatDoesSomething에서 조롱 데이터와 방법을 작성 호출을 테스트하는 간단한 예제입니다.

    @RunWith(MockitoJUnitRunner.class)
    public class CreateTest {
    
        @InjectMocks
        Create create;
        @Mock
        ComponentThatDoesSomething componentThatDoesSomething;
    
        @Test
        public void testCallWithCounterOf4() {
    
            when(componentThatDoesSomething.getCounter()).thenReturn(4);
            String result = create.call();
            assertEquals("Hello World 4", result);
        }
    }
    
  4. from https://stackoverflow.com/questions/39892534/testing-a-controller-with-an-auto-wired-component-is-null-when-calling-the-contr by cc-by-sa and MIT license