2013-11-22 5 views
0

Я перехожу от grails 1.3.6 до 2.2.4. У меня в настоящее время проблемы с использованиемNewSession во время теста интеграции. Я создал демо-проект, чтобы более четко представлять проблему. Код ниже:Grails 2.2 Интеграционный тест терпит неудачу при использовании сNewSession

class DomainA { 
String id 
String domainB 
String description 

static constraints = 
{ 
    id unique: true, nullable:false 
    domainB (nullable: false, blank:false, 
    validator:{val, obj -> 
     if(val != null) 
     { 
      DomainA.withNewSession{session -> 
       def result = DomainB.findByDescription(val) 
       if(result == null) 
       { 
        return 'foreignkey' 
       } 
      } 
     } 

    }) 
} 

static mapping = 
{ 
    table 'DOMAIN_A' 
    id column:'id', type: 'string', generator: 'assigned' 
    version false 
    domainB column:'DOMAIN_B' 
} 

} 



class DomainB { 

String id 
String description 

static constraints = 
{ 
    id unique: true, nullable:false 
    description nullable:false 
} 
static mapping = 
{ 
    table 'DOMAIN_B' 
    id column:'id', type: 'string', generator: 'assigned' 
    version false 
} 
} 

И интеграционный тест

import static org.junit.Assert.* 
import org.junit.* 
class WithNewSessionTestTests extends GroovyTestCase{ 

@Before 
void setUp() { 
    DomainB b = new DomainB(description:"BEE") 
    b.id = "B" 
    b.save(flush:true, failOnError:true) 
    DomainA a = new DomainA(domainB:"BEE", description:"EHH") 
    a.id = "A" 
    a.save(flush:true, failOnError:true) 
} 
@Test 
void testSomething() { 
    assertTrue true 
} 
} 

Тест терпит неудачу, когда a пытается спасти. Возвращаемый код ошибки - «foreignkey», это то, что возвращается, когда DomainA не может найти экземпляр DomainB. Отладка также показывает мне, что значение результата DomainB.findByDescription(val) равно null. Любые идеи о том, как обойти это? Я хочу, чтобы мои тесты продолжали быть транзакционными для avo

Этот тест будет успешным, если я либо удалю withNewSession из проверки, либо если я установил тест на static transactional = false. Любые идеи о том, как сохранить как вызов withNewSession, так и транзакционный характер теста?

Версии: Grails 2.2.4, Oracle 10+, Java 7.0.21, заводной 2.0.7

+0

Эй, я сейчас модернизируюсь от Grails 136 до 224. Был ли это нормально работать в 136? И какова идея использования NewSession против использования того же сеанса в валидаторе? Вы не столкнетесь с той же проблемой во время выполнения? –

+0

Он отлично работал в 1.3.6. Вы не получите проблему во время выполнения, только во время интеграционных тестов. Причина, по которой я использовал withNewSession, заключалась в том, чтобы избежать спячки спящего режима до того, как выполняется 'find'.Промывка при вызове пользовательского валидатора создает бесконечную ошибку переполнения цикла/стека. – Joseph

+0

Можете ли вы попробовать обертывание domainB save с помощьюTransaction {..}? –

ответ

0

Изменить

class DomainA { 
String id 
String domainB 
String description 
----- rest of the code 
} 

в

class DomainA { 
String id 
DomainB domainB 
String description 
} 

В тесте интеграции

import static org.junit.Assert.* 
import org.junit.* 
class WithNewSessionTestTests extends GroovyTestCase{ 

@Before 
void setUp() { 
    DomainB b = new DomainB(description:"BEE") 
    b.id = "B" 
    b.save(flush:true, failOnError:true) 
    DomainA a = new DomainA(domainB:b, description:"EHH") 
    a.id = "A" 
    a.save(flush:true, failOnError:true) 
} 
@Test 
void testSomething() { 
    assertTrue true 
} 
} 

Это должно сработать.

Редактировать

От Grails Integration Test

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

class MyServiceTests extends GroovyTestCase { 
    static transactional = false 
    void testMyTransactionalServiceMethod() { 
     … 
    } } 

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

Без static transactional = false то тест должен сохраняться в БД, и в тесте интеграции, данные rolledback и не сохраняются в базе данных.

+0

Это не решает основной проблемы сохранения транзакционного поведения без изменения базового кода приложения. В моем проекте есть другие случаи, когда используется WithNewSession, которые необходимо протестировать. Это простой пример демонстрации отказа. – Joseph

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