Прежде всего, у меня есть следующий метод конечной точки в классе с именем 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";
}
Как вы можете видеть выше, метод принимает в качестве второго параметра a Основной объект.При запуске приложения параметр указывает на ненулевой объект, как и ожидалось.Он содержит информацию о пользователе, который в данный момент вошел в приложение.
Я создал тестовый класс для 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();
}
}
. Как вы можете видеть из этого второго фрагмента, я пытался смоделировать объект Principal в тестовом классе., используя реализацию UsernamePasswordAuthenticationToken .
Когда я запускаю тест, я получаю NullPointerException , и трассировка стека указывает на следующую строку из первого фрагмента кода:
User user = (User)((UsernamePasswordAuthenticationToken)principal).getPrincipal();
Основной объект, переданный в качестве параметра методу listRecipes from, по-прежнему равен нулю, хотя я пытался предоставить фиктивный объект.
Есть предложения?