簡體   English   中英

Spring REST - 如何檢索返回資源的id?

[英]Spring REST - How can I retrieve the id of the returned resource?

我有一個成功的集成測試,但我想加入其中。

@Test
public void testAdd() throws Exception {
    HttpHeaders httpHeaders = Common.createAuthenticationHeaders("stephane" + ":" + PASSWORD);

    this.mockMvc.perform(
        post("/admin").headers(httpHeaders)
        .contentType(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON)
        .content("{ \"firstname\" : \"" + admin0.getFirstname() + "\", \"lastname\" : \"" + admin0.getLastname() + "\", \"email\" : \"" + admin0.getEmail() + "\", \"login\" : \"" + admin0.getLogin() + "\", \"password\" : \"" + admin0.getPassword() + "\", \"passwordSalt\" : \"" + admin0.getPasswordSalt() + "\" }")
    ).andDo(print())
    .andExpect(status().isCreated())
    .andExpect(jsonPath("$.firstname").value(admin0.getFirstname()))
    .andExpect(jsonPath("$.lastname").value(admin0.getLastname()))
    .andExpect(jsonPath("$.email").value(admin0.getEmail()))
    .andExpect(jsonPath("$.login").value(admin0.getLogin()))
    .andExpect(jsonPath("$.password").value(admin0.getPassword()))
    .andExpect(jsonPath("$.passwordSalt").value(admin0.getPasswordSalt()))
    .andExpect(header().string("Location", Matchers.containsString("/admin/")))
    .andReturn();
}

例如,我可以在新創建的資源上發送GET請求。

然后我可以對它做一個DELETE請求,然后再一次以GET結束。

這是一個明智的集成測試場景嗎?

為此,我需要檢索創建的資源的id。

有什么辦法嗎?

謝謝 !

斯特凡

我可以通過這樣做來解決它:

MvcResult result = this.mockMvc.perform(...)。andReturn();

然后使用andReturn()調用將值返回到結果變量中。

String location = result.getResponse()。getHeader(“Location”);

現在我可以使用以下場景進行測試:POST(已創建),GET(已找到),DELETE(ok),GET(未找到)

這是整個測試:

HttpHeaders httpHeaders = Common.createAuthenticationHeaders("stephane" + ":" + PASSWORD);

MvcResult resultPost = this.mockMvc.perform(
    post("/admin").headers(httpHeaders)
    .contentType(MediaType.APPLICATION_JSON)
    .accept(MediaType.APPLICATION_JSON)
    .content("{ \"firstname\" : \"" + admin0.getFirstname() + "\", \"lastname\" : \"" + admin0.getLastname() + "\", \"email\" : \"" + admin0.getEmail() + "\", \"login\" : \"" + admin0.getLogin() + "\", \"password\" : \"" + admin0.getPassword() + "\", \"passwordSalt\" : \"" + admin0.getPasswordSalt() + "\" }")
).andDo(print())
.andExpect(status().isCreated())
.andExpect(jsonPath("$.firstname").value(admin0.getFirstname()))
.andExpect(jsonPath("$.lastname").value(admin0.getLastname()))
.andExpect(jsonPath("$.email").value(admin0.getEmail()))
.andExpect(jsonPath("$.login").value(admin0.getLogin()))
.andExpect(jsonPath("$.password").value(admin0.getPassword()))
.andExpect(jsonPath("$.passwordSalt").value(admin0.getPasswordSalt()))
.andExpect(header().string("Location", Matchers.containsString("/admin/")))
.andReturn();

String location = resultPost.getResponse().getHeader("Location");
Pattern pattern = Pattern.compile("(\\d+)$");
Matcher matcher = pattern.matcher(location);
matcher.find();
Long id = Long.parseLong(matcher.group(), 10);

MvcResult resultGet = this.mockMvc.perform(
        get("/admin/" + id)
        .headers(httpHeaders)
        .contentType(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON))
        .andDo(print())
        .andExpect(status().isFound())
        .andReturn();
String responseContent = resultGet.getResponse().getContentAsString();

this.mockMvc.perform(
        delete("/admin/" + id)
        .headers(httpHeaders)
        .contentType(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON))
        .andDo(print())
        .andExpect(status().isOk());

this.mockMvc.perform(
        get("/admin/" + id)
        .headers(httpHeaders)
        .contentType(MediaType.APPLICATION_JSON)
        .accept(MediaType.APPLICATION_JSON))
        .andDo(print())
        .andExpect(status().isNotFound());

您可以考慮幾個選項,具體取決於您要測試的內容。

最簡單和最快的是模擬您的用戶服務/存儲庫,或者返回用戶詳細信息的任何內容。 使用Mockito,你可以擁有如下代碼:

// At start of test, we have an admin user in the mock database
when(userRepo.findOne(1)).thenReturn(myNewAdmin());

// some activities and assertions...

// At this point, we have deleted the admin, so return null.
when(userRepo.findOne(1)).thenReturn(null);

// more activities and assertions...

或者,如果您正在嘗試對應用程序進行完全集成測試,並且您正在使用JPA,則定義嵌入式內存數據庫相對簡單,該數據庫由HSQLDB或H2等實現。 在這里,您需要在測試上下文中定義單獨的數據源和實體管理器,並配置Hibernate(在測試上下文中)以生成不存在的模式實體。 通過這種方式,您可以測試將實體插入數據庫,以及它們的ID是否正確生成,查詢它們,更新它們並刪除它們。 所有在您的構建過程中。

我最近敲了一個演示應用程序,你可以在GitHub中找到它:

https://github.com/gratiartis/multids-demo

...雖然它演示了多個數據源的使用,但是可能還有更簡單的教程。

我已經創建了一個deletehandler來在測試后立即從數據庫中刪除該項。

在測試中使用deleteHandler:

this.mockMvc.perform(post(...)).andDo(deleteResult(repository));

並在/src/test/java結構中的某處創建以下類:

public class DeleteResultHandler implements ResultHandler {

    private CrudRepository<IDatabaseObject, String> repository;

    public DeleteResultHandler(CrudRepository repository) {
        this.repository = repository;
    }

    public static DeleteResultHandler deleteResult(CrudRepository repository) {
        return new DeleteResultHandler(repository);
    }

    @Override
    public void handle(MvcResult result) throws Exception {
        String location = result.getResponse().getHeader("Location");
        String id = location.substring(location.lastIndexOf("/") + 1);
        Optional<IDatabaseObject> o = repository.findById(id);
        if (!o.isPresent())
            return;
        repository.delete(o.get());
        // repository.deleteById(id);
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM