StoreMenuCopyServiceTest.java 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. package com.ruoyi.system.service;
  2. import static org.junit.jupiter.api.Assertions.assertEquals;
  3. import static org.junit.jupiter.api.Assertions.assertNull;
  4. import static org.junit.jupiter.api.Assertions.assertThrows;
  5. import static org.junit.jupiter.api.Assertions.assertTrue;
  6. import static org.mockito.ArgumentMatchers.any;
  7. import static org.mockito.Mockito.doAnswer;
  8. import static org.mockito.Mockito.lenient;
  9. import static org.mockito.Mockito.never;
  10. import static org.mockito.Mockito.verify;
  11. import static org.mockito.Mockito.verifyNoInteractions;
  12. import static org.mockito.Mockito.when;
  13. import java.math.BigDecimal;
  14. import java.util.ArrayList;
  15. import java.util.List;
  16. import java.util.Locale;
  17. import java.util.Set;
  18. import java.util.concurrent.atomic.AtomicLong;
  19. import org.junit.jupiter.api.AfterAll;
  20. import org.junit.jupiter.api.BeforeAll;
  21. import org.junit.jupiter.api.BeforeEach;
  22. import org.junit.jupiter.api.Test;
  23. import org.junit.jupiter.api.extension.ExtendWith;
  24. import org.mockito.ArgumentCaptor;
  25. import org.mockito.InjectMocks;
  26. import org.mockito.Mock;
  27. import org.mockito.junit.jupiter.MockitoExtension;
  28. import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
  29. import org.springframework.beans.factory.support.DefaultListableBeanFactory;
  30. import org.springframework.context.support.StaticMessageSource;
  31. import org.springframework.test.util.ReflectionTestUtils;
  32. import com.ruoyi.common.exception.ServiceException;
  33. import com.ruoyi.common.utils.spring.SpringUtils;
  34. import com.ruoyi.system.domain.FoodSpecRelation;
  35. import com.ruoyi.system.domain.FoodSpecs;
  36. import com.ruoyi.system.domain.FoodSpecsValue;
  37. import com.ruoyi.system.domain.PosFenlei;
  38. import com.ruoyi.system.domain.PosFood;
  39. import com.ruoyi.system.dto.menu.StoreMenuCopyExecuteRequest;
  40. import com.ruoyi.system.dto.menu.StoreMenuCopyPreviewRequest;
  41. import com.ruoyi.system.dto.menu.StoreMenuCopyPreviewResponse;
  42. import com.ruoyi.system.dto.menu.StoreMenuCopyResult;
  43. import com.ruoyi.system.mapper.FoodSpecRelationMapper;
  44. import com.ruoyi.system.mapper.FoodSpecsMapper;
  45. import com.ruoyi.system.mapper.FoodSpecsValueMapper;
  46. import com.ruoyi.system.mapper.PosFenleiMapper;
  47. import com.ruoyi.system.mapper.PosFoodMapper;
  48. import com.ruoyi.system.service.impl.StoreMenuCopyServiceImpl;
  49. @ExtendWith(MockitoExtension.class)
  50. class StoreMenuCopyServiceTest
  51. {
  52. private static final Long USER_ID = 9L;
  53. private static final Long SOURCE_STORE_ID = 1L;
  54. private static final Long TARGET_STORE_ID = 2L;
  55. private static ConfigurableListableBeanFactory originalBeanFactory;
  56. @BeforeAll
  57. static void initializeMessages()
  58. {
  59. originalBeanFactory = (ConfigurableListableBeanFactory)
  60. ReflectionTestUtils.getField(SpringUtils.class, "beanFactory");
  61. DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
  62. StaticMessageSource messageSource = new StaticMessageSource();
  63. messageSource.setUseCodeAsDefaultMessage(true);
  64. messageSource.addMessage("menu.copy.store.required", Locale.getDefault(), "门店不能为空");
  65. messageSource.addMessage("menu.copy.store.same", Locale.getDefault(), "源门店与目标门店不能相同");
  66. messageSource.addMessage("menu.copy.strategy.invalid", Locale.getDefault(), "冲突处理方式无效");
  67. messageSource.addMessage("merchant.store.access.denied", Locale.getDefault(), "无门店权限");
  68. beanFactory.registerSingleton("messageSource", messageSource);
  69. new SpringUtils().postProcessBeanFactory(beanFactory);
  70. }
  71. @AfterAll
  72. static void restoreMessages()
  73. {
  74. new SpringUtils().postProcessBeanFactory(originalBeanFactory);
  75. }
  76. @Mock
  77. private MerchantStoreAccessService accessService;
  78. @Mock
  79. private PosFenleiMapper categoryMapper;
  80. @Mock
  81. private PosFoodMapper foodMapper;
  82. @Mock
  83. private FoodSpecsMapper specsMapper;
  84. @Mock
  85. private FoodSpecsValueMapper specsValueMapper;
  86. @Mock
  87. private FoodSpecRelationMapper relationMapper;
  88. @InjectMocks
  89. private StoreMenuCopyServiceImpl service;
  90. @BeforeEach
  91. void setUp()
  92. {
  93. lenient().when(accessService.getAccessibleStoreIds(USER_ID))
  94. .thenReturn(Set.of(SOURCE_STORE_ID, TARGET_STORE_ID));
  95. lenient().when(categoryMapper.selectList(any())).thenReturn(CollectionsFixture.emptyCategories());
  96. lenient().when(foodMapper.selectList(any())).thenReturn(CollectionsFixture.emptyFoods());
  97. lenient().when(specsMapper.selectList(any())).thenReturn(CollectionsFixture.emptySpecs());
  98. lenient().when(specsValueMapper.selectList(any())).thenReturn(CollectionsFixture.emptySpecValues());
  99. lenient().when(relationMapper.selectList(any())).thenReturn(CollectionsFixture.emptyRelations());
  100. }
  101. @Test
  102. void preview_shouldReportAddedMergedIdenticalAndDifferentItems()
  103. {
  104. PosFenlei sourceDrinks = category(11L, SOURCE_STORE_ID, "饮品", "2");
  105. PosFenlei sourceMeals = category(12L, SOURCE_STORE_ID, "主食", "2");
  106. PosFenlei targetDrinks = category(21L, TARGET_STORE_ID, "饮品", "2");
  107. when(categoryMapper.selectList(any())).thenReturn(List.of(sourceDrinks, sourceMeals, targetDrinks));
  108. PosFood sourceCoffee = food(101L, SOURCE_STORE_ID, 11L, "咖啡", "2", "100");
  109. PosFood targetCoffee = food(201L, TARGET_STORE_ID, 21L, "咖啡", "2", "100");
  110. PosFood sourceTea = food(102L, SOURCE_STORE_ID, 11L, "红茶", "2", "50");
  111. PosFood targetTea = food(202L, TARGET_STORE_ID, 21L, "红茶", "2", "45");
  112. PosFood sourceBurger = food(103L, SOURCE_STORE_ID, 12L, "汉堡", "2", "80");
  113. when(foodMapper.selectList(any())).thenReturn(
  114. List.of(sourceCoffee, sourceTea, sourceBurger, targetCoffee, targetTea));
  115. StoreMenuCopyPreviewResponse response = service.preview(USER_ID, previewRequest());
  116. assertEquals(1, response.getAddedCategoryCount());
  117. assertEquals(1, response.getMergedCategoryCount());
  118. assertEquals(1, response.getAddedProductCount());
  119. assertEquals(1, response.getIdenticalProductCount());
  120. assertEquals(1, response.getDifferentProductCount());
  121. assertEquals("红茶", response.getDifferences().get(0).getName());
  122. assertEquals(List.of("price"), response.getDifferences().get(0).getFields().stream()
  123. .map(StoreMenuCopyPreviewResponse.FieldDifference::getField)
  124. .toList());
  125. assertEquals("45", response.getDifferences().get(0).getFields().get(0).getTargetValue());
  126. assertEquals("50", response.getDifferences().get(0).getFields().get(0).getSourceValue());
  127. }
  128. @Test
  129. void preview_shouldTreatSameNameInDifferentLanguageAsNewProduct()
  130. {
  131. when(categoryMapper.selectList(any())).thenReturn(List.of(
  132. category(11L, SOURCE_STORE_ID, "饮品", "2"),
  133. category(21L, TARGET_STORE_ID, "饮品", "2")));
  134. when(foodMapper.selectList(any())).thenReturn(List.of(
  135. food(101L, SOURCE_STORE_ID, 11L, "Cola", "1", "40"),
  136. food(201L, TARGET_STORE_ID, 21L, "Cola", "2", "40")));
  137. StoreMenuCopyPreviewResponse response = service.preview(USER_ID, previewRequest());
  138. assertEquals(1, response.getAddedProductCount());
  139. assertEquals(0, response.getIdenticalProductCount());
  140. assertEquals(0, response.getDifferentProductCount());
  141. }
  142. @Test
  143. void preview_shouldCountDuplicateSourceCategoriesOnlyOnce()
  144. {
  145. when(categoryMapper.selectList(any())).thenReturn(List.of(
  146. category(11L, SOURCE_STORE_ID, "饮品", "2"),
  147. category(12L, SOURCE_STORE_ID, "饮品", "2")));
  148. StoreMenuCopyPreviewResponse response = service.preview(USER_ID, previewRequest());
  149. assertEquals(1, response.getAddedCategoryCount());
  150. assertEquals(0, response.getMergedCategoryCount());
  151. }
  152. @Test
  153. void preview_shouldRejectMissingStoreBeforeReadingMenu()
  154. {
  155. StoreMenuCopyPreviewRequest request = new StoreMenuCopyPreviewRequest();
  156. request.setTargetStoreId(TARGET_STORE_ID);
  157. assertThrows(ServiceException.class, () -> service.preview(USER_ID, request));
  158. verifyNoInteractions(accessService, categoryMapper, foodMapper, specsMapper, specsValueMapper, relationMapper);
  159. }
  160. @Test
  161. void preview_shouldRejectSameStoreBeforeReadingMenu()
  162. {
  163. StoreMenuCopyPreviewRequest request = new StoreMenuCopyPreviewRequest();
  164. request.setSourceStoreId(SOURCE_STORE_ID);
  165. request.setTargetStoreId(SOURCE_STORE_ID);
  166. assertThrows(ServiceException.class, () -> service.preview(USER_ID, request));
  167. verifyNoInteractions(categoryMapper, foodMapper, specsMapper, specsValueMapper, relationMapper);
  168. }
  169. @Test
  170. void preview_shouldRejectWhenEitherStoreIsOutsideCurrentAccessScope()
  171. {
  172. when(accessService.getAccessibleStoreIds(USER_ID)).thenReturn(Set.of(SOURCE_STORE_ID));
  173. assertThrows(ServiceException.class, () -> service.preview(USER_ID, previewRequest()));
  174. verifyNoInteractions(categoryMapper, foodMapper, specsMapper, specsValueMapper, relationMapper);
  175. }
  176. @Test
  177. void execute_shouldCopyEmptyStoreMenuWithStatusesAndSpecs()
  178. {
  179. PosFenlei sourceCategory = category(11L, SOURCE_STORE_ID, "饮品", "2");
  180. PosFood sourceFood = food(101L, SOURCE_STORE_ID, 11L, "咖啡", "2", "100");
  181. sourceFood.setStackingUp("1");
  182. sourceFood.setToExamine("0");
  183. FoodSpecs sourceSpecs = specs(301L, SOURCE_STORE_ID, "大小", "2");
  184. FoodSpecsValue sourceValue = specValue(401L, 301L, "大杯", "10");
  185. FoodSpecRelation sourceRelation = relation(501L, 101L, 301L);
  186. when(categoryMapper.selectList(any())).thenReturn(List.of(sourceCategory));
  187. when(foodMapper.selectList(any())).thenReturn(List.of(sourceFood));
  188. when(specsMapper.selectList(any())).thenReturn(List.of(sourceSpecs));
  189. when(specsValueMapper.selectList(any())).thenReturn(List.of(sourceValue));
  190. when(relationMapper.selectList(any())).thenReturn(List.of(sourceRelation));
  191. AtomicLong ids = new AtomicLong(1000L);
  192. doAnswer(invocation -> assignId(invocation.getArgument(0), ids.incrementAndGet()))
  193. .when(categoryMapper).insert(any(PosFenlei.class));
  194. doAnswer(invocation -> assignId(invocation.getArgument(0), ids.incrementAndGet()))
  195. .when(specsMapper).insert(any(FoodSpecs.class));
  196. doAnswer(invocation -> assignId(invocation.getArgument(0), ids.incrementAndGet()))
  197. .when(specsValueMapper).insert(any(FoodSpecsValue.class));
  198. doAnswer(invocation -> assignId(invocation.getArgument(0), ids.incrementAndGet()))
  199. .when(foodMapper).insert(any(PosFood.class));
  200. when(relationMapper.insert(any(FoodSpecRelation.class))).thenReturn(1);
  201. StoreMenuCopyResult result = service.execute(USER_ID, executeRequest("KEEP_TARGET"));
  202. assertEquals(1, result.getAddedCategoryCount());
  203. assertEquals(1, result.getAddedProductCount());
  204. assertEquals(0, result.getSkippedProductCount());
  205. assertEquals(0, result.getOverwrittenProductCount());
  206. ArgumentCaptor<PosFood> foodCaptor = ArgumentCaptor.forClass(PosFood.class);
  207. verify(foodMapper).insert(foodCaptor.capture());
  208. PosFood insertedFood = foodCaptor.getValue();
  209. assertEquals(TARGET_STORE_ID, insertedFood.getMdid());
  210. assertEquals("1", insertedFood.getStackingUp());
  211. assertEquals("0", insertedFood.getToExamine());
  212. ArgumentCaptor<FoodSpecs> specsCaptor = ArgumentCaptor.forClass(FoodSpecs.class);
  213. verify(specsMapper).insert(specsCaptor.capture());
  214. assertEquals(TARGET_STORE_ID, specsCaptor.getValue().getMdId());
  215. ArgumentCaptor<FoodSpecsValue> valueCaptor = ArgumentCaptor.forClass(FoodSpecsValue.class);
  216. verify(specsValueMapper).insert(valueCaptor.capture());
  217. assertEquals(specsCaptor.getValue().getId(), valueCaptor.getValue().getParentId());
  218. ArgumentCaptor<FoodSpecRelation> relationCaptor = ArgumentCaptor.forClass(FoodSpecRelation.class);
  219. verify(relationMapper).insert(relationCaptor.capture());
  220. assertEquals(insertedFood.getId(), relationCaptor.getValue().getFoodId());
  221. assertEquals(specsCaptor.getValue().getId(), relationCaptor.getValue().getSpecsId());
  222. }
  223. @Test
  224. void execute_shouldKeepDifferentTargetProductByDefault()
  225. {
  226. stubOneDifferentProductWithoutSpecs();
  227. StoreMenuCopyResult result = service.execute(USER_ID, executeRequest(null));
  228. assertEquals(1, result.getSkippedProductCount());
  229. assertEquals(0, result.getOverwrittenProductCount());
  230. verify(foodMapper, never()).updateMenuCopyContent(any(PosFood.class));
  231. }
  232. @Test
  233. void execute_shouldOverwriteContentAndRelationsWithoutChangingTargetStatus()
  234. {
  235. PosFenlei sourceCategory = category(11L, SOURCE_STORE_ID, "饮品", "2");
  236. PosFenlei targetCategory = category(21L, TARGET_STORE_ID, "饮品", "2");
  237. PosFood sourceFood = food(101L, SOURCE_STORE_ID, 11L, "红茶", "2", "50");
  238. sourceFood.setImage("source.png");
  239. sourceFood.setStackingUp("0");
  240. sourceFood.setToExamine("1");
  241. PosFood targetFood = food(201L, TARGET_STORE_ID, 21L, "红茶", "2", "45");
  242. targetFood.setImage("target.png");
  243. targetFood.setStackingUp("1");
  244. targetFood.setToExamine("0");
  245. FoodSpecs sourceSpecs = specs(301L, SOURCE_STORE_ID, "大小", "2");
  246. FoodSpecs targetSpecs = specs(302L, TARGET_STORE_ID, "大小", "2");
  247. when(categoryMapper.selectList(any())).thenReturn(List.of(sourceCategory, targetCategory));
  248. when(foodMapper.selectList(any())).thenReturn(List.of(sourceFood, targetFood));
  249. when(specsMapper.selectList(any())).thenReturn(List.of(sourceSpecs, targetSpecs));
  250. when(relationMapper.selectList(any())).thenReturn(List.of(relation(501L, 101L, 301L)));
  251. when(foodMapper.updateMenuCopyContent(any(PosFood.class))).thenReturn(1);
  252. when(relationMapper.delete(any())).thenReturn(1);
  253. when(relationMapper.insert(any(FoodSpecRelation.class))).thenReturn(1);
  254. StoreMenuCopyResult result = service.execute(USER_ID, executeRequest("OVERWRITE_TARGET"));
  255. assertEquals(1, result.getOverwrittenProductCount());
  256. ArgumentCaptor<PosFood> updateCaptor = ArgumentCaptor.forClass(PosFood.class);
  257. verify(foodMapper).updateMenuCopyContent(updateCaptor.capture());
  258. PosFood update = updateCaptor.getValue();
  259. assertEquals(201L, update.getId());
  260. assertEquals(new BigDecimal("50"), update.getPrice());
  261. assertEquals("source.png", update.getImage());
  262. assertNull(update.getStackingUp());
  263. assertNull(update.getToExamine());
  264. verify(specsMapper, never()).insert(any(FoodSpecs.class));
  265. verify(specsValueMapper, never()).insert(any(FoodSpecsValue.class));
  266. ArgumentCaptor<FoodSpecRelation> relationCaptor = ArgumentCaptor.forClass(FoodSpecRelation.class);
  267. verify(relationMapper).insert(relationCaptor.capture());
  268. assertEquals(201L, relationCaptor.getValue().getFoodId());
  269. assertEquals(302L, relationCaptor.getValue().getSpecsId());
  270. }
  271. @Test
  272. void execute_shouldBeIdempotentWhenTargetAlreadyMatches()
  273. {
  274. PosFenlei sourceCategory = category(11L, SOURCE_STORE_ID, "饮品", "2");
  275. PosFenlei targetCategory = category(21L, TARGET_STORE_ID, "饮品", "2");
  276. PosFood sourceFood = food(101L, SOURCE_STORE_ID, 11L, "咖啡", "2", "100");
  277. PosFood targetFood = food(201L, TARGET_STORE_ID, 21L, "咖啡", "2", "100");
  278. when(categoryMapper.selectList(any())).thenReturn(List.of(sourceCategory, targetCategory));
  279. when(foodMapper.selectList(any())).thenReturn(List.of(sourceFood, targetFood));
  280. StoreMenuCopyResult result = service.execute(USER_ID, executeRequest("OVERWRITE_TARGET"));
  281. assertEquals(0, result.getAddedCategoryCount());
  282. assertEquals(0, result.getAddedProductCount());
  283. assertEquals(1, result.getSkippedProductCount());
  284. assertEquals(0, result.getOverwrittenProductCount());
  285. verify(categoryMapper, never()).insert(any(PosFenlei.class));
  286. verify(foodMapper, never()).insert(any(PosFood.class));
  287. verify(foodMapper, never()).updateMenuCopyContent(any(PosFood.class));
  288. }
  289. @Test
  290. void execute_shouldRejectUnknownConflictStrategyBeforeReadingMenu()
  291. {
  292. assertThrows(ServiceException.class,
  293. () -> service.execute(USER_ID, executeRequest("OVERWRITE_EVERYTHING")));
  294. verifyNoInteractions(categoryMapper, foodMapper, specsMapper, specsValueMapper, relationMapper);
  295. }
  296. private void stubOneDifferentProductWithoutSpecs()
  297. {
  298. when(categoryMapper.selectList(any())).thenReturn(List.of(
  299. category(11L, SOURCE_STORE_ID, "饮品", "2"),
  300. category(21L, TARGET_STORE_ID, "饮品", "2")));
  301. when(foodMapper.selectList(any())).thenReturn(List.of(
  302. food(101L, SOURCE_STORE_ID, 11L, "红茶", "2", "50"),
  303. food(201L, TARGET_STORE_ID, 21L, "红茶", "2", "45")));
  304. }
  305. private StoreMenuCopyPreviewRequest previewRequest()
  306. {
  307. StoreMenuCopyPreviewRequest request = new StoreMenuCopyPreviewRequest();
  308. request.setSourceStoreId(SOURCE_STORE_ID);
  309. request.setTargetStoreId(TARGET_STORE_ID);
  310. return request;
  311. }
  312. private StoreMenuCopyExecuteRequest executeRequest(String strategy)
  313. {
  314. StoreMenuCopyExecuteRequest request = new StoreMenuCopyExecuteRequest();
  315. request.setSourceStoreId(SOURCE_STORE_ID);
  316. request.setTargetStoreId(TARGET_STORE_ID);
  317. request.setConflictStrategy(strategy);
  318. return request;
  319. }
  320. private PosFenlei category(Long id, Long storeId, String name, String language)
  321. {
  322. PosFenlei category = new PosFenlei();
  323. category.setId(id);
  324. category.setMendid(storeId);
  325. category.setName(name);
  326. category.setLanguage(language);
  327. category.setImg("category.png");
  328. category.setSort("1");
  329. return category;
  330. }
  331. private PosFood food(Long id, Long storeId, Long categoryId, String name, String language, String price)
  332. {
  333. PosFood food = new PosFood();
  334. food.setId(id);
  335. food.setMdid(storeId);
  336. food.setFlId(categoryId);
  337. food.setName(name);
  338. food.setLanguage(language);
  339. food.setPrice(new BigDecimal(price));
  340. food.setImage("food.png");
  341. food.setIntroduce("介绍");
  342. food.setFoodSku("[]");
  343. food.setSort(1L);
  344. food.setRecommend(0L);
  345. food.setStackingUp("0");
  346. food.setToExamine("1");
  347. return food;
  348. }
  349. private FoodSpecs specs(Long id, Long storeId, String title, String language)
  350. {
  351. FoodSpecs specs = new FoodSpecs();
  352. specs.setId(id);
  353. specs.setMdId(storeId);
  354. specs.setTitle(title);
  355. specs.setLanguage(language);
  356. specs.setType("1");
  357. specs.setState("1");
  358. specs.setSort(1);
  359. specs.setIsOpen(true);
  360. specs.setIsDelete(false);
  361. return specs;
  362. }
  363. private FoodSpecsValue specValue(Long id, Long parentId, String name, String price)
  364. {
  365. FoodSpecsValue value = new FoodSpecsValue();
  366. value.setId(id);
  367. value.setParentId(parentId);
  368. value.setName(name);
  369. value.setPrice(new BigDecimal(price));
  370. value.setState("1");
  371. value.setIsOpen(true);
  372. return value;
  373. }
  374. private FoodSpecRelation relation(Long id, Long foodId, Long specsId)
  375. {
  376. FoodSpecRelation relation = new FoodSpecRelation();
  377. relation.setId(id);
  378. relation.setFoodId(foodId);
  379. relation.setSpecsId(specsId);
  380. return relation;
  381. }
  382. private int assignId(Object entity, long id)
  383. {
  384. if (entity instanceof PosFenlei category)
  385. {
  386. category.setId(id);
  387. }
  388. else if (entity instanceof PosFood food)
  389. {
  390. food.setId(id);
  391. }
  392. else if (entity instanceof FoodSpecs specs)
  393. {
  394. specs.setId(id);
  395. }
  396. else if (entity instanceof FoodSpecsValue value)
  397. {
  398. value.setId(id);
  399. }
  400. return 1;
  401. }
  402. private static final class CollectionsFixture
  403. {
  404. private CollectionsFixture()
  405. {
  406. }
  407. private static List<PosFenlei> emptyCategories()
  408. {
  409. return new ArrayList<>();
  410. }
  411. private static List<PosFood> emptyFoods()
  412. {
  413. return new ArrayList<>();
  414. }
  415. private static List<FoodSpecs> emptySpecs()
  416. {
  417. return new ArrayList<>();
  418. }
  419. private static List<FoodSpecsValue> emptySpecValues()
  420. {
  421. return new ArrayList<>();
  422. }
  423. private static List<FoodSpecRelation> emptyRelations()
  424. {
  425. return new ArrayList<>();
  426. }
  427. }
  428. }