Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 无法模拟RestTemplate.exchange_Spring Boot_Mockito_Tdd_Resttemplate_Mockmvc - Fatal编程技术网

Spring boot 无法模拟RestTemplate.exchange

Spring boot 无法模拟RestTemplate.exchange,spring-boot,mockito,tdd,resttemplate,mockmvc,Spring Boot,Mockito,Tdd,Resttemplate,Mockmvc,作为TDD的一部分,我希望能够测试SpringBoot rest应用程序的每个部分。但是,我无法模拟外部呼叫 应用程序结构 1.很少有内部调用外部rest端点的rest端点。 2.对外部端点的所有调用都是通过本地http客户端进行编排的,该客户端将RestTemplate用作httpClient @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.MOCK, classes = TestD

作为TDD的一部分,我希望能够测试SpringBoot rest应用程序的每个部分。但是,我无法模拟外部呼叫

应用程序结构
1.很少有内部调用外部rest端点的rest端点。
2.对外部端点的所有调用都是通过本地http客户端进行编排的,该客户端将RestTemplate用作httpClient

@RunWith(SpringRunner.class)  

@SpringBootTest(webEnvironment = WebEnvironment.MOCK, classes = TestDrivenDevelopmentWithJavaApplication.class)  

public class TestDrivenDevelopmentWithJavaApplicationTests {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@MockBean
private RestTemplate client;

@Before
public void setup() throws Exception {
    mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
    Structure1Root category = new Structure1Root();
    Category cat = new Category();
    cat.setCategoryName("Test1");
    cat.setDescription("Test");
    category.setD(cat);

    Mockito.when(client.exchange(
            ArgumentMatchers.eq("https://services.odata.org/V2/Northwind/Northwind.svc/Products(1)?$format=json"),
            ArgumentMatchers.eq(HttpMethod.GET), ArgumentMatchers.eq(null),
            ArgumentMatchers.eq(Structure1Root.class)))
            .thenReturn(new ResponseEntity<Structure1Root>(category, HttpStatus.OK));
}

@Test
public void testendpoint1() throws Exception {
    mockMvc.perform(MockMvcRequestBuilders.get("/api/endpoint1?token=1").contentType(MediaType.APPLICATION_JSON))
            .andExpect(content().string(org.hamcrest.Matchers.containsString("Test1")));

}
最后是本地http客户端代码

@Service
public class MyHttpClient<O> {
    @Autowired
    RestTemplate client;

    public MyHttpClient() {
        // TODO Auto-generated constructor stub
    }

    public Response<O> execute(String url, Class<O> generic) {
        ResponseEntity<O> resp = client.exchange(url, HttpMethod.GET, null, generic);
        return new Response<O>(resp.getStatusCode(), resp.getBody());
    }

}
@服务
公共类MyHttpClient{
@自动连线
rest模板客户端;
公共MyHttpClient(){
//TODO自动生成的构造函数存根
}
公共响应执行(字符串url,类通用){
ResponseEntity resp=client.exchange(url,HttpMethod.GET,null,generic);
返回新响应(resp.getStatusCode(),resp.getBody());
}
}
这是我打算在第一个代码块中截取的
client.execute

然而,它似乎从来都不起作用,并且总是返回空值。

问候,

Veera

你在模仿时使用了错误的对象。您应该使用Structure2Root而不是Structure1Root

正确的测试级别低于该级别,它工作得非常好

package com.demo.samples.tdd;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.demo.samples.tdd.responses.Product;
import com.demo.samples.tdd.responses.Structure2Root;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.WebApplicationContext;

import com.demo.samples.tdd.responses.Category;
import com.demo.samples.tdd.responses.Structure1Root;

@RunWith(SpringRunner.class)

@SpringBootTest(webEnvironment = WebEnvironment.MOCK, classes = TestDrivenDevelopmentWithJavaApplication.class)
public class TestDrivenDevelopmentWithJavaApplicationTests {
    @Autowired
    private WebApplicationContext webApplicationContext;
    private MockMvc mockMvc;
    @MockBean
    private RestTemplate client;

    @Before
    public void setup() throws Exception {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
//      Structure1Root category = new Structure1Root();
//      Category cat = new Category();
//      cat.setCategoryName("Test1");
//      cat.setDescription("Test");
//      category.setD(cat);
//
//      Mockito.when(client.exchange(
//              ArgumentMatchers.eq("https://services.odata.org/V2/Northwind/Northwind.svc/Products(1)?$format=json"),
//              ArgumentMatchers.eq(HttpMethod.GET), ArgumentMatchers.eq(null),
//              ArgumentMatchers.eq(Structure1Root.class)))
//              .thenReturn(new ResponseEntity<Structure1Root>(category, HttpStatus.OK));


        Structure2Root category2 = new Structure2Root();
        Product product = new Product();
        product.setProductName("Test1");
        product.setUnitPrice("1");
        category2.setD(product);

        Mockito.when(client.exchange(
                ArgumentMatchers.eq("https://services.odata.org/V2/Northwind/Northwind.svc/Products(1)?$format=json"),
                ArgumentMatchers.eq(HttpMethod.GET), ArgumentMatchers.eq(null),
                ArgumentMatchers.eq(Structure2Root.class)))
                .thenReturn(new ResponseEntity<Structure2Root>(category2, HttpStatus.OK));


    }

    @Test
    public void testendpoint1() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/api/endpoint1?token=1").contentType(MediaType.APPLICATION_JSON))
                .andExpect(content().string(org.hamcrest.Matchers.containsString("Test1")));

    }

}
package com.demo.samples.tdd;
导入静态org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
导入静态org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
导入com.demo.samples.tdd.responses.Product;
导入com.demo.samples.tdd.responses.Structure2Root;
导入org.junit.Before;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入org.mockito.ArgumentMatchers;
导入org.mockito.mockito;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.boot.test.context.SpringBootTest;
导入org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
导入org.springframework.boot.test.mock.mockito.MockBean;
导入org.springframework.http.HttpMethod;
导入org.springframework.http.HttpStatus;
导入org.springframework.http.MediaType;
导入org.springframework.http.ResponseEntity;
导入org.springframework.test.context.junit4.SpringRunner;
导入org.springframework.test.web.servlet.MockMvc;
导入org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
导入org.springframework.test.web.servlet.setup.MockMvcBuilders;
导入org.springframework.web.client.rest模板;
导入org.springframework.web.context.WebApplicationContext;
导入com.demo.samples.tdd.responses.Category;
导入com.demo.samples.tdd.responses.Structure1Root;
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=webEnvironment.MOCK,classes=TestDrivenDevelopmentWithJavaApplication.class)
公共类TestDrivenDevelopmentWithJavaApplicationTests{
@自动连线
私有WebApplicationContext WebApplicationContext;
私有MockMvc-MockMvc;
@蚕豆
私有模板客户端;
@以前
public void setup()引发异常{
mockMvc=MockMvcBuilders.webAppContextSetup(webApplicationContext.build();
//Structure1Root类别=新Structure1Root();
//类别cat=新类别();
//类别setCategoryName(“Test1”);
//类别设置说明(“测试”);
//类别:setD(cat);
//
//Mockito.when(client.exchange(
//ArgumentMatchers.eq(“https://services.odata.org/V2/Northwind/Northwind.svc/Products(1) ?$format=json“,
//ArgumentMatchers.eq(HttpMethod.GET),ArgumentMatchers.eq(null),
//ArgumentMatchers.eq(Structure1Root.class)))
//.然后返回(新响应属性(类别,HttpStatus.OK));
Structure2Root category2=新的Structure2Root();
产品=新产品();
product.setProductName(“Test1”);
产品。设定单价(“1”);
类别2.setD(产品);
Mockito.when(client.exchange(
ArgumentMatchers.eq(“https://services.odata.org/V2/Northwind/Northwind.svc/Products(1) ?$format=json“,
ArgumentMatchers.eq(HttpMethod.GET),ArgumentMatchers.eq(null),
ArgumentMatchers.eq(Structure2Root.class)))
.然后返回(新响应类型(category2,HttpStatus.OK));
}
@试验
public void testendpoint1()引发异常{
mockMvc.perform(MockMvcRequestBuilders.get(“/api/endpoint1?token=1”).contentType(MediaType.APPLICATION_JSON))
.andExpect(content().string(org.hamcrest.Matchers.containsString(“Test1”));
}
}

返回
null
是模拟的默认行为。因此,用于设置模拟的表达式/谓词与实际值不匹配。查看您的方法,它需要一个
Structure2Root
,而不是一个
Structure1Root
,它用于在模拟上设置您的表达式。@M.Deinum:谢谢您的帮助。肯定解决了。一个重要的经验教训是模拟的默认行为。我的误解是,我认为默认行为是调用rest端点,并且只模拟配置了mockito的请求。
package com.demo.samples.tdd;

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import com.demo.samples.tdd.responses.Product;
import com.demo.samples.tdd.responses.Structure2Root;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.context.WebApplicationContext;

import com.demo.samples.tdd.responses.Category;
import com.demo.samples.tdd.responses.Structure1Root;

@RunWith(SpringRunner.class)

@SpringBootTest(webEnvironment = WebEnvironment.MOCK, classes = TestDrivenDevelopmentWithJavaApplication.class)
public class TestDrivenDevelopmentWithJavaApplicationTests {
    @Autowired
    private WebApplicationContext webApplicationContext;
    private MockMvc mockMvc;
    @MockBean
    private RestTemplate client;

    @Before
    public void setup() throws Exception {
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
//      Structure1Root category = new Structure1Root();
//      Category cat = new Category();
//      cat.setCategoryName("Test1");
//      cat.setDescription("Test");
//      category.setD(cat);
//
//      Mockito.when(client.exchange(
//              ArgumentMatchers.eq("https://services.odata.org/V2/Northwind/Northwind.svc/Products(1)?$format=json"),
//              ArgumentMatchers.eq(HttpMethod.GET), ArgumentMatchers.eq(null),
//              ArgumentMatchers.eq(Structure1Root.class)))
//              .thenReturn(new ResponseEntity<Structure1Root>(category, HttpStatus.OK));


        Structure2Root category2 = new Structure2Root();
        Product product = new Product();
        product.setProductName("Test1");
        product.setUnitPrice("1");
        category2.setD(product);

        Mockito.when(client.exchange(
                ArgumentMatchers.eq("https://services.odata.org/V2/Northwind/Northwind.svc/Products(1)?$format=json"),
                ArgumentMatchers.eq(HttpMethod.GET), ArgumentMatchers.eq(null),
                ArgumentMatchers.eq(Structure2Root.class)))
                .thenReturn(new ResponseEntity<Structure2Root>(category2, HttpStatus.OK));


    }

    @Test
    public void testendpoint1() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.get("/api/endpoint1?token=1").contentType(MediaType.APPLICATION_JSON))
                .andExpect(content().string(org.hamcrest.Matchers.containsString("Test1")));

    }

}