0
votes

Se moquer d'une méthode vide dans le cadre de printemps (Makito)

Je suis en train d'écrire des tests d'intégration pour une application Web de printemps et j'ai atteint une étape où j'ai besoin de simuler des appels de méthodes de service qui ont un type de retour avide. J'ai fait des recherches sur certains moyens de le faire, mais aucun ne semble être la bonne façon.

Ce que je veux faire est: p>

  • Lorsque la méthode Enregistrer () est appelée sur Recipesservice, elle devrait enregistrer la recette li> ul>

    ci-dessous, je vais fournir le code et les deux façons principales que j'ai déjà essayées. Si quelqu'un peut aider ce serait génial! P>

    la méthode qui nécessite de se moquer de fort> p> xxx pré>

    le service qui a besoin Appelant (Méthode de sauvegarde) FORT> P>

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = Application.class)
    @WebAppConfiguration
    public class RecipeControllerTests {
    
    private MockMvc mockMvc;
    
    @Mock
    private RecipeService recipeService;
    
    @Mock
    private UserService userService;
    
    @Mock
    private IngredientService ingredientService;
    
    @Autowired
    WebApplicationContext wac;
    
    @InjectMocks
    private RecipeController recipeController;
    
    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).apply(springSecurity()).build();
    }
    
    /**
     * Tests for index pages / & /recipes
     */
    @Test
    @WithUserDetails(value = "daniel")
    public void indexPageLoads() throws Exception {
        List<Recipe> recipes = recipeListBuilder();
        List<Ingredient> ingredients = ingredientsListBuilder();
    
        when(recipeService.findAll()).thenReturn(recipes);
        when(ingredientService.findAll()).thenReturn(ingredients);
        when(userService.findByUsername("daniel")).thenReturn(userBuilder());
    
        mockMvc.perform(get("/recipes"))
                .andExpect(model().attributeExists("recipes", "ingredients", "favs"))
                .andExpect(status().isOk());
    }
    
    /**
     * Tests for page /recipes/add
     */
    @Test
    @WithMockUser
    public void addRecipePageLoads() throws Exception {
        mockMvc.perform(get("/recipes/add"))
                .andExpect(model().attributeExists("task", "buttonAction", "action", "photo", "recipe"))
                .andExpect(status().isOk());
    }
    
    @Test
    @WithUserDetails("daniel")
    public void createNewRecipeRedirects() throws Exception {
        User user = userBuilder();
        Recipe recipe = recipeBuilder(1L);
        recipe.setOwner(user);
        user.addFavorite(recipe);
        MultipartFile photo = new MockMultipartFile("image", "food.jpeg",
                "image/jpeg", "dummy content file".getBytes());
    
        when(userService.findByUsername("daniel")).thenReturn(user);
        verify(recipeService, times(1)).save(recipe, photo);
        verify(userService, times(1)).save(user);
    
    
        mockMvc.perform(post("/recipes/add"))
                .andExpect(redirectedUrl("/recipes"))
                .andExpect(flash().attributeExists("flash"));
    
    
    }
    
    
    private User userBuilder() {
        User user = new User();
        user.setFavorites(recipeListBuilder());
        user.setId(1L);
        user.setRoles(new String[]{"ROLE_USER", "ROLE_ADMIN"});
        user.setUsername("daniel");
        user.setPassword("password");
    
        return user;
    }
    
    private List<Recipe> recipeListBuilder() {
        List<Recipe> recipes =  new ArrayList<>();
        recipes.add(recipeBuilder(1L));
        recipes.add(recipeBuilder(2L));
    
        return recipes;
    }
    
    private List<Ingredient> ingredientsListBuilder() {
        List<Ingredient> ingredients = new ArrayList<>();
        ingredients.add(ingredientBuilder());
    
        return ingredients;
    }
    
    private Ingredient ingredientBuilder() {
        Ingredient ingredient = new Ingredient();
        ingredient.setCondition("good");
        ingredient.setName("test ing");
        ingredient.setQuantity(1);
        ingredient.setId(1L);
    
        return ingredient;
    }
    
    private Recipe recipeBuilder(Long id) {
        Recipe recipe = new Recipe();
        recipe.setName("Test recipe");
        recipe.setDescription("Test Description");
        recipe.setId(id);
        recipe.setCategory(Category.ALL_CATEGORIES);
        recipe.setCookTime(10);
        recipe.setPrepTime(10);
        recipe.addIngredient(ingredientBuilder());
    
        return recipe;
    }
    }
    


12 commentaires

Si vous avez une méthode qui retourne void et que vous souhaitez vous moquer de l'objet de la classe qui possède cette méthode, la manière typique de le faire est de vérifier que cette méthode a été appelée à un objet simulé en utilisant Mockito :: Vérifiez .


En outre, vous n'avez rien dit de ce que vous attendez-vous et ce qui se passe à la place.


Désolé, je devrais être plus explicite. Je veux vous moquer de la sauvegarde de l'appel de service () qui prend un objet de recette et un multipartfile.


Il suffit d'utiliser Mockito :: Vérifier Pour tester si votre logique appelée Enregistrer la méthode sur votre moce car vous ne voulez probablement pas tester la logique d'économie ici.


Je viens d'essayer cela et j'ai reçu l'erreur suivante: "Je voulais mais non invoqué: recipesservice.save (com.danielturato.recipe.recipe.recipe@1f1574c, org.springframework.mock.web.mockmultipartfile@16c9e378); -> com.danielturato.recipe.recipe.RecipecontrollertestS.Createn EwreciperDirects (RE CIPECONTROLERTESS. JAVA: 112) En fait, il y avait des interactions nulle avec ce simulacre. "


Cela signifie que votre logique n'a pas invoqué la méthode. Probablement résultat.haserrors () retourné true.


Ou que la logique appelée sauvegarde () sur une autre instance de recettes. Montrez-nous votre test complet, mais minimal.


Je vais ajouter mon code de test maintenant


Vous devez appeler Mockito :: Vérifier Après le MockMVC.Perform () ... Vous souhaitez tester que la logique de traitement de votre demande a été invoquée sur votre moce. Mockito :: Vérifier est utilisé pour affirmer, non pour configurer des simulacres.


Voilà. Vous utilisez un test d'intégration Spring, où le ressort crée un service et des contrôleurs réels et commence un contexte d'application Web réel. Donc, le contrôleur et les services qu'il utilise n'ont rien à voir avec les services de simulation et le contrôleur que vous créez vous-même dans le test à l'aide du Mockito @mock et @InjectMocks annotations . Vous devez utiliser le @mockbean des annotations de printemps pour indiquer le ressort de créer une fusion de service de service, injecter dans le contrôleur et dans votre test.


Même lorsque je mets la vérification () en dessous de la zone PEFORM (), je reçois cette erreur voulue mais non invoquée. Aussi, que voulez-vous dire par @Mockbean Annotation et où je le mettrai-je


docs.spring.io/spring-boot/docs/current/reeference/htmlsingle / ...


3 Réponses :


0
votes

Si vous avez une logique que vous souhaitez tester un appareil à tester et que cette logique invoque des méthodes d'autre composant que vous souhaitez simuler et certaines de ces méthodes renvoient void code> - la manière typique de tester votre logique est Pour vérifier que votre logique a effectivement appelé les méthodes code> Void code> d'objet moquée. Vous pouvez y parvenir en utilisant Mockito :: Vérifier CODE>:

 Mockito.verify(recipeService, Mockito.times(1)).save(any(Recipe.class), any(MultipartFile.class));


0 commentaires

0
votes

Si vous moquez la méthode de sauvegarde, j'utiliserais l'un des "do ..." Docs Bien sûr, cela suggère que votre méthode a un effet secondaire quelque part.

Si vous souhaitez vous assurer qu'une méthode est appelée, vous pouvez utiliser «Vérifier» comme mentionné dans d'autres réponses.

Généralement moqueur vous permet de remplacer une certaine collaboration / fonctionnalité avec une version sous le contrôle des tests où la vérification permet de vérifier quelque chose survenu (ou non)


0 commentaires

1
votes

Essayez Mockito.Donothing () : Il dit essentiellement à Mockito de ne rien faire lorsqu'un procédé d'un objet simulé est appelé: xxx


0 commentaires