Как вы издеваетесь над статическим методом объекта домена в Grails?

имеет объект домена Grails, который имеет собственную статическую функцию для захвата данных из базы данных

class Foo {
    /* member variables, mapping, constraints, etc. */

    static findByCustomCriteria(someParameter, List listParameter) {
        /* code to get stuff from the database... */

        /*
            Return value is a map
            ["one": "uno", "two": "due", "three": "tre"]
        */
    }

}

Статическая функция findByCustomCriteria использует createCriteria() для построения запроса, который извлекает данные из таблицы Foo, что означает, что mockDomain(Foo) не работает должным образом при модульном тестировании. То, что я пытаюсь сделать, чтобы обойти это, - использовать один из методов общего назначения насмешек над mock out findByCustomCriteria, но я не могу правильно получить синтаксис.

У меня есть контроллер BarController, который я пытаюсь проверить, и похоронен в вызове BarController.someFunction(), есть вызов Foo.findByCustomCriteria().

class BarControllerTest extends ControllerUnitTestCase {

    protected void setUp() {
        super.setUp()
    }

    protected void tearDown() {
        super.tearDown()
    }

    void testSomeFunction() {

        /* Mocking for Foo goes here */

        assertEquals("someValue", controller.someFunction())
    }
}

Каким образом можно было бы издеваться над этим?

Я пробовал использовать new MockFor(), mockFor() и metaClass, но я не могу заставить его работать.


Edit:

Каждый раз, когда я пытался издеваться над этим, я пытался издеваться над этим так...

Foo.metaClass.'static'.findByCustomCriteria = { someParam, anotherParam ->
    ["one": "uno", "two": "due", "three": "tre"]
}

Я предполагаю, что я не включал достаточно информации изначально.

Ответ 1

Я встречался с этим сценарием несколько раз, вам нужно изменить статический метаклас Foo:

Foo.metaClass.'static'.findByCustomCriteria = { someParameter, List listParameter ->
    ["one": "uno", "two": "due", "three": "tre"]
}

Обычно я помещаю его в тестовую настройку, поэтому не забываю, когда это нужно применить.

Ответ 2

В Grails 2.0 и выше вы можете использовать класс GrailsMock, подобный этому

def mockControl = new GrailsMock(MyDomainClass)
mockControl.demand.static.get() {id -> return null}  // Static method
...
mockControl.verify()

Смотрите здесь.