'How to test my update method with Mockito

Here is my test Class:

@RunWith(SpringRunner.class)
@SpringBootTest
public class UpdateRestaurantTest {

    @MockBean
    private RestaurantRepository restaurantRepository;

    @Autowired
    private RestaurantController restaurantController;

    @Before
    public void init() {

        Set<Menu> menuSetTest = new HashSet<Menu>();
        Menu menuTest= new Menu("starterTest", "dishTest", "dessertTest");
        menuSetTest.add(menuTest);
        Restaurant restaurant = new Restaurant("IdRestaurant", "RestaurantTest","MonAddressTest", menuSetTest);
        Mockito.when(restaurantRepository.save(restaurant)).thenReturn(restaurant);
        Mockito.when(restaurantRepository.findById("IdRestaurant")).thenReturn(Optional.of(restaurant));

        String idRestaurant = restaurantController.create(restaurant);

        System.out.println(idRestaurant);
    }


    @Test
    public void updateRestaurant() {
        Set<Menu> menuSetTest = new HashSet<Menu>();
        Menu menuTest= new Menu("starterTest", "dishTest", "dessertTest");
        menuSetTest.add(menuTest);
        Restaurant restaurant = new Restaurant("IdRestaurant", "RestaurantUpdate","MonAddressTest", menuSetTest);
        Mockito.doNothing().when(restaurantRepository).update("IdRestaurant", restaurant);
        restaurantController.update("IdRestaurant", restaurant);

        ArrayList<Restaurant> restaurants = new ArrayList<Restaurant>();
        restaurants.add(restaurantController.findById("IdRestaurant"));
        assertEquals(restaurants.get(0).getName(), "RestaurantUpdate");


    }
}

and here is the return...

org.opentest4j.AssertionFailedError: expected: <RestaurantTest> but was: <RestaurantUpdate>
Expected :RestaurantTest
Actual   :RestaurantUpdate
<Click to see difference>

He doesn't execute my update... I also had to define in the repository the "update" method because Spring doesn't know it! The "Mockito.doNothing() exists because my service implementation returns "void".

Here is my entity:

package com.api.restaurant.model;

import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name="restaurant")
@NoArgsConstructor
@AllArgsConstructor
public class Restaurant {

    @Id
    @GeneratedValue(generator = "system-uuid")
    @GenericGenerator(name = "system-uuid", strategy ="uuid")
    private String id;

    @Column(name="name")
    private String name;

    @Column(name="address")
    private String address;

    @OneToMany(cascade = CascadeType.ALL) // Deleting a restaurant delete all menus
    @Column(name="menus")
    private Set<Menu> menus = new HashSet<>(); // Set is a way to exclude duplicates menus in a same restaurant

    public Restaurant(String name, String address, Set<Menu> menus) {
        this.name = name;
        this.address = address;
        this.menus = menus;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Set<Menu> getMenus() {
        return menus;
    }

    public void setMenus(Set<Menu> menus) {
        this.menus = menus;
    }

    @Override
    public String toString() {
        return "Restaurant{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", menus=" + menus.toString() +
                '}';
    }
}

Here is my repository: (I am not sure for the "update" function, I use it to call it from my test class...)

package com.api.restaurant.dao;

import com.api.restaurant.model.Restaurant;
import org.springframework.data.repository.CrudRepository;

public interface RestaurantRepository extends CrudRepository<Restaurant, String> {


    void update(String idRestaurant, Restaurant restaurant);
}

Here is my service:

package com.api.restaurant.service;

import com.api.restaurant.model.Restaurant;

import java.util.List;
import java.util.Map;

public interface RestaurantService {

    public List<Restaurant> findAll();


    public Restaurant findById(String id);

    String create(Restaurant restaurant);

    void update(String id, Restaurant restaurant);

    void partialUpdate(String idRestaurant, Map<String, Object> updates);

    void deleteById(String idRestaurant);
}

Here is the implementation of my service:

package com.api.restaurant.service.impl;

import ch.qos.logback.core.net.SyslogOutputStream;
import com.api.restaurant.dao.RestaurantRepository;
import com.api.restaurant.model.Restaurant;
import com.api.restaurant.service.RestaurantService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class RestaurantServiceImpl implements RestaurantService {

    @Autowired
    private RestaurantRepository restaurantRepository;

    @Override
    public List<Restaurant> findAll() {
        List<Restaurant> myList = new ArrayList<Restaurant>();
        restaurantRepository.findAll().forEach(myList::add);
        for(Restaurant tempRestau : myList){
            System.out.println(tempRestau.toString());
        }

        return myList;
    }

    public Restaurant findById(String id){
        if(restaurantRepository.findById(id).isPresent())
            return restaurantRepository.findById(id).get();
        else
            return null;

    }

    @Override
    public String create(Restaurant restaurant) {
       return restaurantRepository.save(restaurant).getId();
    }

    @Override
    public void update(String id, Restaurant restaurant) {
        restaurant.setId(id);
        restaurantRepository.save(restaurant);
    }

    @Override
    public void partialUpdate(String idRestaurant, Map<String, Object> updates) {
        Restaurant restaurantUpdate = restaurantRepository.findById(idRestaurant).get();
        for(String key : updates.keySet()){
            switch (key){
                case "name" :
                    restaurantUpdate.setName((String) updates.get(key));
                    break;
                case "address" :
                    restaurantUpdate.setAddress((String) updates.get(key));
                    break;
            }
        }
        restaurantRepository.save(restaurantUpdate);
    }

    @Override
    public void deleteById(String idRestaurant) {
        restaurantRepository.deleteById(idRestaurant);
    }
}

Here is my controller:

package com.api.restaurant.rest;


import com.api.restaurant.model.Restaurant;
import com.api.restaurant.service.RestaurantService;
import com.api.restaurant.util.CrudPrecondition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/restaurants")
public class RestaurantController {

    @Autowired
    private RestaurantService restaurantService;

    @GetMapping
    public List<Restaurant> findAll(){

        return restaurantService.findAll();
    }

    @GetMapping("/{id}")
    public Restaurant findById(@PathVariable("id") String idRestaurant){
        Restaurant restaurant = restaurantService.findById(idRestaurant);
        CrudPrecondition.checkfound(restaurant);
        return restaurant;
    }

    @PostMapping()
    @ResponseStatus(code = HttpStatus.CREATED)
    public String create(@RequestBody Restaurant restaurant){
        return restaurantService.create(restaurant);
    }

    @PutMapping("/{id}")
    @ResponseStatus(code = HttpStatus.OK)
    public void update(@PathVariable("id") String idRestaurant, @RequestBody Restaurant restaurant){
        CrudPrecondition.checkfound(restaurantService.findById(idRestaurant));
        restaurantService.update(idRestaurant, restaurant);


    }

    @PatchMapping("/{id}")
    @ResponseStatus(code = HttpStatus.OK)
    public void partialUpdate(@PathVariable("id") String idRestaurant, @RequestBody Map<String, Object> updates){
        CrudPrecondition.checkfound(restaurantService.findById(idRestaurant));
        restaurantService.partialUpdate(idRestaurant, updates);
    }

    @DeleteMapping("/{id}")
    @ResponseStatus(code = HttpStatus.OK)
    public void deleteById(@PathVariable("id") String idRestaurant){
        CrudPrecondition.checkfound(restaurantService.findById(idRestaurant));
        restaurantService.deleteById(idRestaurant);

    }
}


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source