【问题标题】:Mocking two Users at once for testing a 2-player Game?一次模拟两个用户来测试一个 2 人游戏?
【发布时间】:2020-09-21 02:01:44
【问题描述】:

以下是迄今为止我的 MVC 应用程序的测试套件。我正在使用 Spring Security 进行授权,到目前为止,我已经能够在测试中使用 @WithMockUser 注释来处理它(user1 在 testCreateNewGame() 中创建游戏,而 user2 在 testJoinNewGame() 中加入其中之一)。

我想为玩游戏的两个用户编写一个测试方法。这将需要来自两个不同用户的对相同控制器的多次调用。有没有一种简单的方法可以通过注释来做到这一点?如果可能的话,我想避免在多个测试方法之间来回传递状态。

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class WebApplicationTest {

    @Autowired
    private MockMvc mockMvc;

    @Autowired
    private UserService userService;

    private static boolean firstUse = true;

    @Before
    public void saveUsers(){
        if (firstUse) {
            User user1 = new User();
            user1.setUsername("user1");
            user1.setPassword("pwd");
            User user2 = new User();
            user2.setUsername("user2");
            user2.setPassword("pwd");
            userService.save(user1);
            userService.save(user2);
            firstUse = false;
        }
    }

    @Test
    @WithMockUser(username = "user1", password = "pwd", roles = "USER")
    public void testCreateNewGame() throws Exception {
        String s = new ObjectMapper().writeValueAsString(new HashMap<String, Integer>(){{put("numPlayers", 2);}});
        mockMvc.perform(post("/game/create")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(s))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("WAIT_FOR_PLAYERS_TO_JOIN")));
        mockMvc.perform(post("/game/create")
                .contentType(MediaType.APPLICATION_JSON_UTF8)
                .content(s))
                .andExpect(status().isOk())
                .andExpect(content().string(containsString("WAIT_FOR_PLAYERS_TO_JOIN")));
    }

    @Test
    @WithMockUser(username = "user2", password = "pwd", roles = "USER")
    public void testJoinGame() throws Exception {
        MvcResult mvcResult = mockMvc.perform(get("/game/list")).andReturn();
        Game[] games = new ObjectMapper().readValue(mvcResult.getResponse().getContentAsString(), Game[].class);
        assert(games.length == 2);
    }
}

【问题讨论】:

    标签: spring-mvc mockito integration-testing spring-test-mvc


    【解决方案1】:

    由于@WithMockUser 注解将使用定义的用户来执行整个测试方法,因此您无法使用此注解在一个测试中模拟两个用户。

    您可以做的是使用Spring Security integration with testing MVC 应用程序的编程方法,例如:

    // first call in test
    mvc
        .perform(post("/game/create")
        .with(user("admin").password("pass").roles("USER","ADMIN")))
    
    // second call in test
    mvc
        .perform(post("/game/create")
        .with(user("duke").password("pass").roles("USER")))
    

    为此,您应该从测试方法中删除@WithMockUser

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-09
      • 2021-12-04
      • 1970-01-01
      • 2010-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多