Java Spring引导控制器测试-当返回列表不工作时Mockito
我在模仿我的Java Spring引导控制器测试-当返回列表不工作时Mockito,java,spring-boot,mockito,Java,Spring Boot,Mockito,我在模仿我的MemberServiceImpl类。特别是下面的getMembers()方法,它返回List: @服务 公共类MemberServiceImpl实现MemberService{ 私有记录器Logger=LoggerFactory.getLogger(this.getClass()); @自动连线 成员库; @凌驾 公共列表getMembers(){ List members=repository.findAll(); 返回成员; } 在我的MemberControllerTest
MemberServiceImpl
类。特别是下面的getMembers()
方法,它返回List
:
@服务
公共类MemberServiceImpl实现MemberService{
私有记录器Logger=LoggerFactory.getLogger(this.getClass());
@自动连线
成员库;
@凌驾
公共列表getMembers(){
List members=repository.findAll();
返回成员;
}
在我的MemberControllerTest
课程中,我创建了一个高尔夫球手列表,并在发送我的GET
请求之前使用whenthenReturn(members)
,该请求总是返回一个空列表。你知道我做错了什么吗:
@SpringBootTest(webEnvironment=webEnvironment.RANDOM\u端口)
类成员控制器测试{
@嘲弄
会员服务会员服务;
@注射模拟
MemberController MemberController=新的MemberController();
@自动连线
私有TestRestTemplate;
//绑定随机端口
@本地服务器端口
专用int端口;
私有字符串name=“David”;
私人高尔夫球手会员=新高尔夫球手(“大卫”);
私有HttpHeaders=新HttpHeaders();
专用字符串baseUrl=”http://localhost:";
@试验
void testGetAllMembers()引发异常{
restTemplate=新的TestRestTemplate();
HttpHeaders=新的HttpHeaders();
高尔夫球手会员1=新高尔夫球手(“哈里”);
高尔夫球手会员2=新高尔夫球手(“莫林”);
列表成员=新的ArrayList();
成员。添加(成员1);
增加(成员2);
当(memberService.getMembers())。然后返回(members);
ResponseEntity response=restTemplate.exchange(“http://localhost:+端口,HttpMethod.GET,null,新参数化类型引用(){});
assertEquals(成员,response.getBody());
}
}
应用程序(测试)上下文不会拾取您的模拟。因此,即使您模拟您的服务并将其注入测试中的控制器实例,当您对(测试)应用程序发出请求时,该控制器实例也不是应用程序上下文将使用的实例
不要使用@Mock和@InjectMocks,而是创建一个TestConfiguration类,并使用@MockBean代替serviceinpl。将控制器从测试中一起删除,因为您不必与它交互。例如:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Import(MemberControllerTestConfiguration.class)
class MemberControllerTest {
@Autowired
MemberService memberService;
@Autowired
private TestRestTemplate restTemplate;
//rest of your test
}
@TestConfiguration
class MemberControllerTestConfiguration{
@MockBean
MemberService memberService;
}
我通常倾向于将Testconfiguration粘贴在同一个测试文件的底部,以将它们放在一起,因为这只是此测试将使用的内容。如果模拟bean开始抱怨太多bean,则可能必须使用@Primary对其进行注释因此,即使您模拟您的服务并将其注入测试中的控制器实例中,当您对(测试)应用程序发出请求时,该控制器实例并不是应用程序上下文将使用的实例 不要使用@Mock和@InjectMocks,而是创建一个TestConfiguration类,并使用@MockBean代替serviceinpl。将控制器从测试中一起删除,因为您不必与它交互。例如:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Import(MemberControllerTestConfiguration.class)
class MemberControllerTest {
@Autowired
MemberService memberService;
@Autowired
private TestRestTemplate restTemplate;
//rest of your test
}
@TestConfiguration
class MemberControllerTestConfiguration{
@MockBean
MemberService memberService;
}
我通常倾向于将Testconfiguration粘贴在同一个测试文件的底部,以将它们放在一起,因为这只是此测试将要使用的东西。如果模拟的bean开始抱怨太多bean,您可能必须用@Primary注释它您正在模拟控制器对象,但希望它处理req让Spring像正常应用程序启动一样创建控制器,无需自己定义 但是您需要将
MemberService
的定义更改为@MockBean
,这意味着当Spring需要一个服务将其注入到它创建的控制器中时,它将使用这个MockBean:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MemberControllerTest {
@MockBean
MemberService memberService;
@Autowired
private TestRestTemplate restTemplate;
//bind RANDOM_PORT
@LocalServerPort
private int port;
private String name = "David";
private Golfer member = new Golfer("David");
private HttpHeaders headers = new HttpHeaders();
private String baseUrl = "http://localhost:";
@Test
void testGetAllMembers() throws Exception{
restTemplate = new TestRestTemplate();
HttpHeaders headers = new HttpHeaders();
Golfer member1 = new Golfer("Harry");
Golfer member2 = new Golfer("Maureen");
List<Golfer> members = new ArrayList<Golfer>();
members.add(member1);
members.add(member2);
when(memberService.getMembers()).thenReturn(members);
ResponseEntity<List<Golfer>> response = restTemplate.exchange("http://localhost:"+port, HttpMethod.GET, null, new ParameterizedTypeReference<List<Golfer>>() {});
assertEquals(members,response.getBody());
}
}
@SpringBootTest(webEnvironment=webEnvironment.RANDOM\u端口)
类成员控制器测试{
@蚕豆
会员服务会员服务;
@自动连线
私有TestRestTemplate;
//绑定随机端口
@本地服务器端口
专用int端口;
私有字符串name=“David”;
私人高尔夫球手会员=新高尔夫球手(“大卫”);
私有HttpHeaders=新HttpHeaders();
专用字符串baseUrl=”http://localhost:";
@试验
void testGetAllMembers()引发异常{
restTemplate=新的TestRestTemplate();
HttpHeaders=新的HttpHeaders();
高尔夫球手会员1=新高尔夫球手(“哈里”);
高尔夫球手会员2=新高尔夫球手(“莫林”);
列表成员=新的ArrayList();
成员。添加(成员1);
增加(成员2);
当(memberService.getMembers())。然后返回(members);
ResponseEntity response=restTemplate.exchange(“http://localhost:+端口,HttpMethod.GET,null,新参数化类型引用(){});
assertEquals(成员,response.getBody());
}
}
您正在模拟控制器对象,但希望它能够处理请求。让Spring像在正常应用程序启动时一样创建控制器,无需自行定义
但是您需要将MemberService
的定义更改为@MockBean
,这意味着当Spring需要一个服务将其注入到它创建的控制器中时,它将使用这个MockBean:
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MemberControllerTest {
@MockBean
MemberService memberService;
@Autowired
private TestRestTemplate restTemplate;
//bind RANDOM_PORT
@LocalServerPort
private int port;
private String name = "David";
private Golfer member = new Golfer("David");
private HttpHeaders headers = new HttpHeaders();
private String baseUrl = "http://localhost:";
@Test
void testGetAllMembers() throws Exception{
restTemplate = new TestRestTemplate();
HttpHeaders headers = new HttpHeaders();
Golfer member1 = new Golfer("Harry");
Golfer member2 = new Golfer("Maureen");
List<Golfer> members = new ArrayList<Golfer>();
members.add(member1);
members.add(member2);
when(memberService.getMembers()).thenReturn(members);
ResponseEntity<List<Golfer>> response = restTemplate.exchange("http://localhost:"+port, HttpMethod.GET, null, new ParameterizedTypeReference<List<Golfer>>() {});
assertEquals(members,response.getBody());
}
}
@SpringBootTest(webEnvironment=webEnvironment.RANDOM\u端口)
类成员控制器测试{
@蚕豆
会员服务会员服务;
@自动连线
私有TestRestTemplate;
//绑定随机端口
@本地服务器端口
专用int端口;
私有字符串name=“David”;
私人高尔夫球手会员=新高尔夫球手(“大卫”);
私有HttpHeaders=新HttpHeaders();
专用字符串baseUrl=”http://localhost:";
@试验
void testGetAllMembers()t