Bulk update with JSON
Different API spec
It has different API spec compared to others and I’ll talk about it this time.
:: different points ::
- /restaurants/{id}/menuitems
- collection data (List<menuitems>)
- save
- deleteById
0. Setting
I want to put menuitem.json into restaurant(id=1) which is kind of bulk update.

1. Create menuitems.json file
[
{
"name" : "Cake"
},
{
"name" : "Coffee"
}
]

2. Create new controller and test for MenuItem
:: cautions ::
- …/{restaurantId}/…
- it seems weird first time because I’m used to integer type
@RestController
public class MenuItemController {
@PatchMapping("/restaurants/{restaurantId}/menuitems")
public String bulkUpdate(){
return "";
}
}

Now bulkUpdate() method exists but doesn’t run just returns “ ”
@RunWith(SpringRunner.class)
@WebMvcTest(MenuItemController.class)
public class MenuItemControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void bulkUpdate() throws Exception {
mvc.perform(patch("/restaurants/1/menuitems")
.contentType(MediaType.APPLICATION_JSON)
.content("[]"))
.andExpect(status().isOk());
}
}

— — — — passed
3. create MenuItemService in application
I need something action in the test, so I clarify menuitem service Class by making bulkUpdate() method.
verify(menuItemService).bulkUpdate();

red sign => go to MenuItemService

— — — -failed
Wanted but not invoked

It means that it never run in controller, and I have to designate specific action of bulkUpdate() method in MenuItemController..!
@Autowired
private MenuItemService menuItemService;
@PatchMapping("/restaurants/{restaurantId}/menuitems")
public String bulkUpdate(){
menuItemService.bulkUpdate();
return "";
}

— — — — passed
It runs but bulkUpdate() method is empty.
4. bulk update what? menuitem list
@PatchMapping("/restaurants/{restaurantId}/menuitems")
public String bulkUpdate(){
List<MenuItem> menuItems = new ArrayList<>();
menuItemService.bulkUpdate(menuItems);
return "";
}@Test
public void bulkUpdate() throws Exception {
mvc.perform(patch("/restaurants/1/menuitems")
.contentType(MediaType.APPLICATION_JSON)
.content("[]"))
.andExpect(status().isOk());
verify(menuItemService).bulkUpdate(any());
}
— -passed
5. where did I get new data(menuitem list)? input JSON file.
@RequestBody
@PatchMapping("/restaurants/{restaurantId}/menuitems")
public String bulkUpdate(@RequestBody List<MenuItem> menuItems){
menuItemService.bulkUpdate(menuItems);
return "";
}
and to sign ‘menuitem is from restaurant id=n’
@PatchMapping("/restaurants/{restaurantId}/menuitems")
public String bulkUpdate(@PathVariable Long restaurantId, @RequestBody List<MenuItem> menuItems){
menuItemService.bulkUpdate(restaurantId, menuItems);
return "";
}
— -failed

- eq….?

6. bulkupdate activation => save
@Service
public class MenuItemService {
@Autowired
private MenuItemRepository menuItemRepository;
public void bulkUpdate(Long restaurantId, List<MenuItem> menuItems) {
MenuItem menuItem = new MenuItem();
menuItemRepository.save(menuItem);
}
}

@RunWith(SpringRunner.class)
@SpringBootTest
public class MenuItemServiceTest {
private MenuItemService menuItemService
@Mock
private MenuItemRepository menuItemRepository;
@Before
public void setup(){
MockitoAnnotations.initMocks(this); menuItemService = new MenuItemService(menuItemRepository);
}
@Test
public void bulkUpdate(){
List<MenuItem> menuItems= new ArrayList<MenuItem>();
MenuItem menuItem = new MenuItem();
menuItem.setName("avocado-smoothie");
menuItems.add(menuItem);
menuItemService.bulkUpdate(1L, menuItems);
verify(menuItemRepository).save(any());
}
}

— — failed nullpoint error
@Autowired
private MenuItemRepository menuItemRepository;
public MenuItemService(MenuItemRepository menuItemRepository){
this.menuItemRepository = menuItemRepository;
}
— — — passed
7. automatically create (for 문)
public void bulkUpdate(Long restaurantId, List<MenuItem> menuItems) {
for(MenuItem menuItem : menuItems) {
menuItemRepository.save(menuItem);
}
}
and test twice
@Test
public void bulkUpdate(){
List<MenuItem> menuItems= new ArrayList<MenuItem>();
MenuItem menuItem = new MenuItem();
menuItem.setName("avocado-smoothie");
menuItems.add(menuItem);
MenuItem menuItem2 = new MenuItem();
menuItem.setName("cheese-cake");
menuItems.add(menuItem2);
menuItemService.bulkUpdate(1L, menuItems);
verify(menuItemRepository, times(2)).save(any());
}
8. link restuarant id
public void bulkUpdate(Long restaurantId, List<MenuItem> menuItems) {
for(MenuItem menuItem : menuItems) {
menuItem.setRestaurantId(restaurantId);
menuItemRepository.save(menuItem);
}
}
— passed
9. terminal check


restaurants/1 => menuitem show
restaurants => null
@Transient //임시로 처리 (db에 저장하려고 만든 것 아님)
@JsonInclude(JsonInclude.Include.NON_NULL)
private List<MenuItem> menuItems = new ArrayList<MenuItem>();
Restaurant.java
I got question “when should I use verify()?”
It intends to perform “patch things” first, and prove it through “verify(object)”