mockForConstraintsTests абстрактный классный класс - PullRequest
1 голос
/ 11 июля 2009

Модульное тестирование Абстрактные классы в Groovy

Я задавал предыдущий вопрос о модульном тестировании и насмешке над классом домена, но я не думаю, что я был достаточно конкретен. У меня есть класс домена:

package toplevel.domain

abstract class Party {
    static hasMany = [roles:PartyRole]
    static constraints = {
        roles(nullable:true)
        dateCreated(display:false)
        lastUpdated(display:false)
    }
    List roles
    Date dateCreated
    Date lastUpdated
}

Вот мой модульный тест:

import grails.test.*
import toplevel.domain.*

class PartyTests extends GrailsUnitTestCase {
    Party party
    protected void setUp() {
        super.setUp()
        party = [:] as Party
        mockForConstraintsTests(Party, [party])
    }

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

    void testNullRolesIsValid() {
        party.roles = null
        assertTrue "The roles should be nullable", party.validate()
    }
}

Вот результаты теста: Не удалось создать новый экземпляр класса [toplevel.domain.Party]!

org.codehaus.groovy.grails.exceptions.NewInstanceCreationException: Не удалось создать новый экземпляр класса [toplevel.domain.Party]! в grails.test.MockUtils.prepareForConstraintsTests (MockUtils.groovy: 540) at grails.test.MockUtils $ prepareForConstraintsTests.call (Неизвестно Источник) в grails.test.GrailsUnitTestCase.mockForConstraintsTests (GrailsUnitTestCase.groovy: 111) на PartyTests.setUp (PartyTests.groovy: 9) на _GrailsTest_groovy $ _run_closure4.doCall (_GrailsTest_groovy: 203) в _GrailsTest_groovy $ _run_closure4.call (_GrailsTest_groovy) в _GrailsTest_groovy $ _run_closure2.doCall_________T_: в _GrailsTest_groovy $ _run_closure1.doCall (_GrailsTest_groovy: 96) в TestApp $ _run_closure1.doCall (TestApp.groovy: 66) в gant.Gant $ _dispatch_closure4.doCall (Gant.groovy: 324) в gant.Gant $ _dispatch_closure6.doCall (Gant.groovy: 334) в gant.Gant $ _dispatch_closure6.doCall (Gant.groovy) в gant.Gant.withBuildListeners (Gant.groovy: 344) в gant.Gant.this $ 2 $ с помощью BuildListeners (Gant.groovy) в gant.Gant $ this $ 2 $ withBuildListeners.callCurrent (Неизвестный источник) в gant.Gant.dispatch (Gant.groovy: 334) в gant.Gant.this $ 2 $ отправка (Gant.groovy) в gant.Gant.invokeMethod (Gant.groovy) в gant.Gant.processTargets (Gant.groovy: 495) в gant.Gant.processTargets (Gant.groovy: 480) Причина: java.lang.InstantiationException

Я не понимаю. Я создал экземпляр класса и передал его методу mockForConstraintsTests. Что я делаю не так?

Ответы [ 2 ]

3 голосов
/ 11 июля 2009

Вам нужно предоставить конкретный класс Party, тест пытается создать экземпляр класса Party, а не может, так как он абстрактный. Я переработал ваш тест ниже и прокомментировал места, где я внес изменения.

package toplevel.domain

import grails.test.*
import toplevel.domain.*

// Create a stub implementation class
class PartyImpl extends Party { }

class PartyTests extends GrailsUnitTestCase {
    Party party
    protected void setUp() {
        super.setUp()
        //party = [:] as Party
        // Create an instance of the stub'd class
        party = new PartyImpl()
        //mockForConstraintsTests(Party, [party])
        // Need to pass in the concrete class as first arg
        mockForConstraintsTests(PartyImpl, [party])
    }

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

    void testNullRolesIsValid() {
        party.roles = null
        assertTrue "The roles should be nullable", party.validate()
    }
}
2 голосов
/ 11 июля 2009

На самом деле это проблема способа, с помощью которого материал mockForConstraintsTests работает в grails, а не проблема использования этого типа mock, обычно в groovy.

Этот тип макетов просто не совместим с макетами, которые создаются mockForConstraintsTests. Если вы хотите использовать эту библиотеку, Джон прав в том, что просто создает и передает простой конкретный элемент класса.

Я на самом деле не большой поклонник насмешек с ограничениями, которые есть в последних версиях Grails, поскольку они не "настоящие", и большая часть вычеркнутых вещей отличается от реального кода, который запускается при подключении в реальную базу данных. Я предпочитаю использовать интеграционные тесты для проверки такого рода ограничений.

Если вы поместите свой тестовый класс в интеграционные тесты и удалите вызов mockForConstraintsTests, ваш код будет работать:

package toplevel.domain

import grails.test.*

class PartyTests extends GrailsUnitTestCase {
    Party party
    protected void setUp() {
        super.setUp()
        party = [:] as Party
    }

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

    void testNullRolesIsValid() {
        party.roles = null
        assertTrue "The roles should be nullable", party.validate()
    }
}

Результаты:

Running 1 integration test...
Running test PartyTests...PASSED
Tests Completed in 226ms ...
-------------------------------------------------------
Tests passed: 1
Tests failed: 0
-------------------------------------------------------
...