2013-11-12 5 views
0

Я новичок в grails/groovy, поэтому, пожалуйста, простите меня за эту простую проблему, но я действительно пробовал все, и я не преуспел. В общем, я хочу написать действительно простой модульный тест для моего метода обслуживания. Но я не могу понять, почему мой макет не имеет списка.Mocking domain object не работает

Моей служба:

class MenuService { 

def mailService 

def prepareMenu() { 
    def newDinners = [] 
    def soups = Dish.findAllWhere(dishKind: DishKind.SOUP) 
    def mainCourses = Dish.findAllWhere(dishKind: DishKind.MAIN_COURSE) 
    def salads = Dish.findAllWhere(dishKind: DishKind.SALAD) 
    def menu = checkIfMenuExists(Menu.last()) 

    deleteUsedMainCoursesAndSoups(menu, soups, mainCourses) 
    deleteUsedSalads(menu, salads) 

    Collections.shuffle(mainCourses) 
    mainCourses = mainCourses.subList(0, 7); 

    mainCourses.each { 
     Dinner dinner = new Dinner() 
     dinner.mainCourse = it 
     if (it.withSoup) { 
      Collections.shuffle(soups) 
      dinner.soup = soups.get(0) 
      soups.remove(0) 
     } 
     newDinners.add(dinner) 
    } 

    Collections.shuffle(salads) 
    salads = salads.subList(0, 2) 

    menu.dinners = newDinners 
    menu.salads = salads 

    menu.save() 
    sendMenu(menu) 
} 

private void deleteUsedSalads(Menu menu, salads) { 
    if (!menu.salads.isEmpty()) { 
     menu.salads.each { 
      if (salads.contains(it)) { 
       salads.remove(it) 
      } 
     } 
    } 
} 

private void deleteUsedMainCoursesAndSoups(Menu menu, soups, mainCourses) { 
    if (!menu.dinners.isEmpty()) { 
     menu.dinners.each { 
      if (mainCourses.contains(it.mainCourse)) { 
       mainCourses.remove(it) 
      } else if (soups.contains(it.soup)) 
       soups.remove(it) 
     } 
    } 
} 

private Menu checkIfMenuExists(Menu menu) { 
    if (menu == null) { 
     menu = new Menu() 
     menu.dinners = new ArrayList<Dinner>() 
     menu.salads = new ArrayList<Dish>() 
    } 
    menu 
} 

def sendMenu(Menu menu) { 
    mailService.sendMail { 
     to "" 
     subject "" 
     body(view: "/mail", model: [dinners: menu.dinners, salads: menu.salads]) 
    } 
} 

} 

и у меня есть тест для этого:

@TestFor(MenuService) 
@Mock([Dish, Menu]) 
@TestMixin(DomainClassUnitTestMixin) 
class MenuServiceTests { 
def menuService = new MenuService() 

void testIfItChoosesNewMenu() { 

    def soups = [ 
      new Dish(name: "Soup 1", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 2", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 3", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 4", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 5", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 6", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 7", dishKind: DishKind.SOUP, ingredients: "") 
    ] 
    def mainCourses = [ 
      new Dish(name: "Main course 1", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 2", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 3", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 4", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 5", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 6", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 7", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 8", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 9", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 10", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 11", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 12", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 13", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 14", dishKind: DishKind.MAIN_COURSE, ingredients: "") 
    ] 
    def salads = [ 
      new Dish(name: "Salad 1", dishKind: DishKind.SALAD, ingredients: ""), 
      new Dish(name: "Salad 2", dishKind: DishKind.SALAD, ingredients: ""), 
      new Dish(name: "Salad 3", dishKind: DishKind.SALAD, ingredients: ""), 
      new Dish(name: "Salad 4", dishKind: DishKind.SALAD, ingredients: ""), 
    ] 

    mockDomain(Dish, [soups, mainCourses, salads]) 
    Menu menu = menuService.prepareMenu() 

    assertEquals 2, menu.salads.size() 
    assertEquals 7, menu.dinners.size() 
} 

} 

Когда я запускаю тест у меня есть неисправность:

Failure: testIfItChoosesNewMenu(familyhelper.MenuServiceTests) 
java.lang.IndexOutOfBoundsException: toIndex = 7 
at java.util.SubList.<init>(AbstractList.java:602) 
at java.util.RandomAccessSubList.<init>(AbstractList.java:758) 
at java.util.AbstractList.subList(AbstractList.java:468) 
at familyhelper.MenuService.prepareMenu(MenuService.groovy:18) 
at familyhelper.MenuServiceTests.testIfItChoosesNewMenu(MenuServiceTests.groovy:51) 

потому что:

def soups = Dish.findAllWhere(dishKind: DishKind.SOUP) 
    def mainCourses = Dish.findAllWhere(dishKind: DishKind.MAIN_COURSE) 
    def salads = Dish.findAllWhere(dishKind: DishKind.SALAD) 

пустые. Я прочитал, что все динамические функции для объектов домена вводятся при добавлении аннотации @Mock, но даже это мне не помогает. Кто-нибудь знает, как исправить этот тест? Заранее спасибо

ответ

1

Возможно, вы забыли сохранить посуду,

def salads = [ 
      new Dish(name: "Salad 1", dishKind: DishKind.SALAD, ingredients: "").save(), 
      new Dish(name: "Salad 2", dishKind: DishKind.SALAD, ingredients: "").save(), 
      new Dish(name: "Salad 3", dishKind: DishKind.SALAD, ingredients: "").save(), 
      new Dish(name: "Salad 4", dishKind: DishKind.SALAD, ingredients: "").save(), 
    ] 
+0

Нет, я добавил его, но не повезло. –

2

Вам не нужно явно издеваются класс домена. @Mock должен сделать это за вас.

@TestFor(MenuService) 
@Mock([Dish, Menu]) 
class MenuServiceTests { 

    void testIfItChoosesNewMenu() { 

     def soups = [ 
      new Dish(name: "Soup 1", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 2", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 3", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 4", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 5", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 6", dishKind: DishKind.SOUP, ingredients: ""), 
      new Dish(name: "Soup 7", dishKind: DishKind.SOUP, ingredients: "") 
     ] 

     def mainCourses = [ 
      new Dish(name: "Main course 1", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 2", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 3", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 4", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 5", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 6", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 7", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 8", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 9", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 10", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 11", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 12", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 13", dishKind: DishKind.MAIN_COURSE, ingredients: ""), 
      new Dish(name: "Main course 14", dishKind: DishKind.MAIN_COURSE, ingredients: "") 
     ] 

     def salads = [ 
      new Dish(name: "Salad 1", dishKind: DishKind.SALAD, ingredients: ""), 
      new Dish(name: "Salad 2", dishKind: DishKind.SALAD, ingredients: ""), 
      new Dish(name: "Salad 3", dishKind: DishKind.SALAD, ingredients: ""), 
      new Dish(name: "Salad 4", dishKind: DishKind.SALAD, ingredients: "") 
     ] 

     //Save the domain classes 
     [soups, mainCourses, salads].each{it*.save(flush: true, failOnError: true)} 

     //Note service is auto injected by @TestFor 
     //SO no need to instantiate 
     Menu menu = service.prepareMenu() 

     assertEquals 2, menu.salads.size() 
     assertEquals 7, menu.dinners.size() 
    } 
} 

Если вы еще не осведомлены о build test data плагина, то я бы предложил использовать его для такого рода испытаний. В целом, я бы также предложил использовать spock в качестве тестовой среды.

+0

Спасибо за ваше предложение, я постараюсь посмотреть на этот плагин, я действительно новичок в Grails. Но все же я хотел бы знать, что не так с моим тестом. Я пробовал ваши изменения, но все же мой тест терпит неудачу hm .. –

+0

Какая ошибка вы получаете? @MariuszGrodek – dmahapatro

+0

Вы можете увидеть ошибку в моем вопросе. Его просто OutBound..Exception, потому что списки пустые, потому что у них нет моих издевающихся данных. –

1

Чтобы найти что-то в БД с GORM вам нужно сохранить это первый. @Alidad был прав, но вы, вероятно, следует использовать:

new Dish(...).save(false) 

false в save отключает вашу проверку домена объекта.

+0

Я тоже пробовал, но не повезло: / –

Смежные вопросы