即使在进行模拟后,Null仍会传递给自动接线服务-SpringBootTest

时间:2019-06-08 18:23:15

标签: spring-boot junit mocking mockito spring-boot-test

我想对我的API进行集成测试。

@RestController
@RequestMapping("/api/v1")
public class TestController {

    @Autowired
    TestService testService;

    @RequestMapping("/welcome")
    public String welcomeMessage(@RequestParam("name") String name) {
        return testService.welcomeMessage(name);
    }
}

下面是服务接口及其实现:

public interface TestService {
    public String welcomeMessage(String name);
}

public class TestServiceImpl implements TestService{
    @Autowired
    TestRepository repo;

    @Override
    public String welcomeMessage(String name) {
        repo.save(new StringEntity(name));
        return "Hello "+name;
    }
}

下面是测试用例:

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class MockitoTestingApplicationTests {

    @Autowired
    MockMvc mvc;

    @MockBean
    TestService testService;

    @MockBean
    TestController testController;

    @Test
    public void contextLoads() throws Exception {
        Mockito.when(testController.welcomeMessage(ArgumentMatchers.anyString())).thenCallRealMethod();
        Mockito.when(testService.welcomeMessage(ArgumentMatchers.anyString())).thenCallRealMethod();

        mvc.perform(get("/api/v1/welcome").param("name", "dude")).andExpect(status().isOk());
    }

}

我有几个问题。

  1. 当我执行上面的代码时,它抛出一个错误,说不能在抽象方法上调用真实方法。当我嘲笑TestServiceImpl时,它会在Controller中抛出NullPointerException,因为TestService为空。我该如何解决?

  2. 在使用MongoDB时,我应该如何模拟存储库层。当我尝试模拟MongoTemplate时,它抛出一个错误,提示MongoConvertor must not be null

  3. 这是编写测试用例的正确方法。不使用thenCallRealMethod()就能覆盖代码吗?

请建议我如何进行。预先感谢。

1 个答案:

答案 0 :(得分:1)

请确保您已实现服务的实现,即 <div id="registerstandard" class="modal fade"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div class="modal-header col-md-12"> <img class=" logo_h modallogo" src="img/logo.svg"> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">&times;</span> </button> </div> <div class="modal-body signupmessage"> <img src="img/marketing.svg" alt="" class="img-fluid modalicon"> <h3 class="col-md-12 formtext py-4">eCommerce Standard</h3> <p class="text-center">Please fill in the form below, we will then send you an email to confirm where to send your products.</p> <form id="contactform2" method="post" name="contactform2" onsubmit="return false;"> <div class="form-group pt-3"> <label class="sr-only pt-5" for="name">Name</label> <input type="text" class="form-control form-control-danger form-control-lg" name="name" id="Name" placeholder="Name*"> </div> <div class="form-group"> <label class="sr-only" for="mail">Email</label> <input type="email" class="form-control form-control form-control-lg" name="email" id="mail" placeholder="Email*"> </div> <div class="form-group"> <label class="sr-only" for="mail">Phone Number</label> <input type="phone" class="form-control form-control form-control-lg" name="phone" id="phone" placeholder="Phone Number"> </div> <div class="row"> <div class="col-md-12"> <div class="form-group"> <input type="checkbox" id="gdpr" name="gdpr" class="form-control md-textarea"></textarea> <label for="gdpr" name="gdprlabel">I have read and consent to my data being collected as outlined in the <a href="http://www.hopkinsons.net/privacy-policy" target="_blank" class="disclaimerLink">Disclaimer</a></label> </div> </div> </div> <div class="modal-footer py-4"> <button type="submit" class="button button-header bg">Submit</button> </div> </form> </div> </div> </div> </div> 带有TestServiceImpl注释(如果严格意义上不是服务,则为@Service),并使用间谍代替模拟:

@Component

默认情况下,监视会调用真实方法,因此您必须模拟这些您不想调用的实现。

关于存储库,您应该模拟用@SpyBean TestService testService; 注释的组件,而不是其中使用的实际@Repository / SessionFactory等。