【问题标题】:Spring MVC Test failingSpring MVC 测试失败
【发布时间】:2015-11-27 16:09:45
【问题描述】:

我正在尝试运行 Spring MVC 测试,但不断收到此异常。

org.springframework.web.util.NestedServletException:请求处理失败;嵌套异常是 java.lang.NullPointerException

发生异常是因为自动装配的依赖关系,

    @Autowired
    private AccountService accountService;

没有在测试中注入(在测试之外工作正常)。

谁能帮我解决这个问题。这是我的代码:

//AccountControllerITest 类

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MockServletContext.class)
@WebAppConfiguration
public class AccountControllerITest {

private MockMvc mvc;

ObjectMapper om;

@Before
public void setUp() throws Exception {
    mvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();
}

@Test
public void getAccounts() throws Exception {
    MvcResult mvcResult =     mvc.perform(MockMvcRequestBuilders.get("/api/accounts"))
            .andExpect(status().isOk())
            .andReturn();
}    
}

}

//账户控制器

@RestController
@RequestMapping("/api/accounts")
public class AccountController {

@Autowired
private AccountService accountService;

@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Set<AccountInfo>> getAccounts(@RequestParam(value = "firstName", required = false) String firstName,
                                                    @RequestParam(value = "surName", required = false)  String surName) {
    Set<AccountInfo> accounts = accountService.getAccounts(firstName, surName);
    return new ResponseEntity<>(accounts, HttpStatus.OK);
}

}

感谢您的帮助!

【问题讨论】:

  • 使用构造函数注入。

标签: java spring spring-mvc spring-mvc-test spring-ioc


【解决方案1】:

因为您使用的是独立设置:mvc = MockMvcBuilders.standaloneSetup(new AccountController()).build();。如果您通过new AccountController() 创建控制器,Spring 没有机会注入accountService,因为它不控制实例的创建和连接。

你有两个选择:

  1. 将您的测试切换到单元测试,不要使用SpringJUnit4ClassRunnerMockServletContext at 全部。可以使用@InjectMocks注入私有accountService

    public class AccountControllerITest {
    
        private MockMvc mvc;
    
        ObjectMapper om;
    
        @Mock
        private AccountController accountController = new AccountController();
    
        @InjectMocks
        private AccountService accountService = new Mockito.mock(AccountService.class);
    
        @Before
        public void setUp() throws Exception {
            mvc = MockMvcBuilders.standaloneSetup(accountController).build();
        }
    

    您还可以将增强功能应用于您的控制器。将字段注入替换为构造函数注入,您可以在测试中通过构造函数将accountService 传递给控制器​​。这样你就根本不需要使用@InjectMocks

  2. 使用 webAppContext 设置:

    @Autowired
    private WebApplicationContext webApplicationContext;
    
    @BeforeMethod
    public void init() {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    }
    

【讨论】:

  • @Ikmac- 感谢您的回复。您能否进一步解释问题所在,因为我不明白。谢谢
  • 感谢您的帮助。我选择了选项 2。我现在明白问题所在了。谢谢你的解释!
【解决方案2】:

您需要配置您的测试以注入您的自动装配属性。见以下代码块:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class AccountControllerITest {

    // ... your test code

    @Configuration
    public static class YourConfiguration {

        @Bean
        AccountService accountService() {
            // init and return your AccountService
        }
    }
}

您可以使用Mockito 初始化您的AccountService

【讨论】:

  • 这无济于事,因为他正在将集成与单元测试混合在一起。
猜你喜欢
  • 2016-06-13
  • 2017-02-12
  • 2016-04-30
  • 1970-01-01
  • 2012-12-16
  • 1970-01-01
  • 1970-01-01
  • 2018-05-10
  • 2012-04-27
相关资源
最近更新 更多