gpt4 book ai didi

java - 如何在Spring中正确模拟Principal对象?

转载 作者:行者123 更新时间:2023-12-02 01:39:42 25 4
gpt4 key购买 nike

首先,我在名为 RecipeController 的类中存在以下端点方法:

@RequestMapping(value = {"/", "/recipes"})
public String listRecipes(Model model, Principal principal){
List<Recipe> recipes;
User user = (User)((UsernamePasswordAuthenticationToken)principal).getPrincipal();
User actualUser = userService.findByUsername(user.getUsername());
if(!model.containsAttribute("recipes")){
recipes = recipeService.findAll();
model.addAttribute("nullAndNonNullUserFavoriteRecipeList",
UtilityMethods.nullAndNonNullUserFavoriteRecipeList(recipes, actualUser.getFavoritedRecipes()));

model.addAttribute("recipes", recipes);
}

if(!model.containsAttribute("recipe")){
model.addAttribute("recipe", new Recipe());
}

model.addAttribute("categories", Category.values());
model.addAttribute("username", user.getUsername());
return "recipe/index";
}

正如您在上面所看到的,该方法将 Principal 对象作为第二个参数。运行应用程序时,参数按预期指向非空对象。它包含有关当前在应用程序中登录的用户的信息。

我为RecipeController创建了一个名为RecipeControllerTest的测试类。此类包含一个名为 testListRecipes 的方法。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@WebAppConfiguration
public class RecipeControllerTest{

@Mock
private RecipeService recipeService;

@Mock
private IngredientService ingredientService;

@Mock
private StepService stepService;

@Mock
private UserService userService;

@Mock
private UsernamePasswordAuthenticationToken principal;

private RecipeController recipeController;

private MockMvc mockMvc;

@Before
public void setUp(){
MockitoAnnotations.initMocks(this);

recipeController = new RecipeController(recipeService,
ingredientService, stepService, userService);

mockMvc = MockMvcBuilders.standaloneSetup(recipeController).build();
}

@Test
public void testListRecipes() throws Exception {
User user = new User();

List<Recipe> recipes = new ArrayList<>();
Recipe recipe = new Recipe();
recipes.add(recipe);

when(principal.getPrincipal()).thenReturn(user);
when(userService.findByUsername(anyString()))
.thenReturn(user);
when(recipeService.findAll()).thenReturn(recipes);

mockMvc.perform(get("/recipes"))
.andExpect(status().isOk())
.andExpect(view().name("recipe/index"))
.andExpect(model().attributeExists("recipes"))
.andExpect(model().attributeExists("recipe"))
.andExpect(model().attributeExists("categories"))
.andExpect(model().attributeExists("username"));

verify(userService, times(1)).findByUsername(anyString());
verify(recipeService, times(1)).findAll();
}
}

正如您在第二个代码片段中看到的,我尝试使用 UsernamePasswordAuthenticationToken 实现来模拟测试类中的 Principal 对象。

当我运行测试时,我得到一个NullPointerException,并且堆栈跟踪将我指向第一个代码片段中的以下行:

User user = (User)((UsernamePasswordAuthenticationToken)principal).getPrincipal();

作为参数传递给 listRecipes 方法的主体对象仍然为 null,即使我尝试提供一个模拟对象。

有什么建议吗?

最佳答案

创建一个实现 Principal 的类:

class PrincipalImpl implements Principal {

@Override
public String getName() {

return "XXXXXXX";
}

}

示例测试:

@Test
public void login() throws Exception {
Principal principal = new PrincipalImpl();

mockMvc.perform(get("/login").principal(principal)).andExpect(.........;

}

关于java - 如何在Spring中正确模拟Principal对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54616189/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com