WebTestClient mutateWith 显然没有变异

WebTestClient mutateWith apparently not mutating

我使用 WebTestClient 的(Cucumber)BDD 单元测试失败(带有 403 Forbidden),而我认为它应该通过。经过一些调试,我确定这是因为 CSRF 检查失败,这表明 mutateWith(csrf()) 操作不起作用。我做错了什么?


我的测试场景:

  Scenario Outline: Login
    Given that player "<player>" exists with  password "<password>"
    And presenting a valid CSRF token
    When log in as "<player>" using password "<password>"
    Then program accepts the login

我的测试步骤代码(注意client.mutateWith(csrf())的存在):


@SpringBootTest(...)
@AutoConfigureWebTestClient
public class WebSteps {

   @Autowired
   private WebTestClient client;

...

   private WebTestClient.ResponseSpec response;

   @Given("presenting a valid CSRF token")
   public void presenting_a_valid_CSRF_token() {
      client.mutateWith(csrf());
   }

   @When("log in as {string} using password {string}")
   public void log_in_as_using_password(final String player,
            final String password) {
      response = client.post().uri("/login")
               .contentType(MediaType.APPLICATION_FORM_URLENCODED)
               .body(BodyInserters.fromFormData("username", player)
                        .with("password", password))
               .exchange();
   }

   @Then("program accepts the login")
   public void program_accepts_the_login() {
      response.expectStatus().isFound().expectHeader().valueEquals("Location",
               "/");
   }

...

尽管名称如此,mutateWith() 方法并没有真正改变它的对象。相反,它 returns 一个应用了突变的新对象。因此而不是写

   @Given("presenting a valid CSRF token")
   public void presenting_a_valid_CSRF_token() {
      client.mutateWith(csrf());
   }

   @Given("presenting a valid CSRF token")
   public void presenting_a_valid_CSRF_token() {
      client = client.mutateWith(csrf());
   }

由于测试步骤改变共享状态(client 对象)的方式,而不是使用具有长链的流畅 API,因此在 Cucumber 测试中更可能发生此错误通话次数。