2014-06-13 33 views
5

Jestem nowy dla Groovy i Grails. Test Spocka dla obiektu domeny, który ma zostać przetestowany, nie powiódł się z powodu przekonwertowania pustego ciągu na wartość null. Oto kod. Przedmiotem domenydlaczego ciągi puste są konwertowane na wartość null, przechodząc do konstruktora obiektu domeny w Grails 2.4.0?

class Todo { 

    String name 
    Date createdDate 
    String priority 
    String status 

    static constraints = { 
     priority blank: true 
    } 

} 

Specyfikacja Spock

@TestFor(Todo) 
class TodoSpec extends Specification { 

    void "test persist"() { 
     when: 
     new Todo(name: 't1', createdDate: new Date(), priority: "1", status: 'ok').save() 
     new Todo(name: 't2', createdDate: new Date(), priority: '', status: 'ok').save() 

     then: 
     Todo.list().size() == 2 
    } 

} 

Wynikiem grails test-app jest

Todo.list().size() == 2 
    |  |  | 
    |  1  false 
    [collab.todo.Todo : 1] 
     at collab.todo.TodoSpec.test persist(TodoSpec.groovy:18) 

, że okazało się, że pusty ciąg '' w linii new Todo(name: 't2', createdDate: new Date(), priority: '', status: 'ok') przekształca się null przez debugowanie. Po pewnym czasie przez Google widzę, że w Grails jest funkcja konwertująca puste ciągi z formularza internetowego na wartość null, która może być wyłączona przez konfigurację grails.databinding.convertEmptyStringsToNull = false w Config.groovy. Ale nie sądzę, że tak jest w przypadku Spock UT. Próbowałem, ale to nie działa tak, jak myślałem.

Zastanawiam się, dlaczego pusty ciąg jest konwertowany na wartość null jako parametr przechodzący do konstruktora? Z góry dziękuję.

Odpowiedz

6

Jest trochę hinky teraz, ale można pracować dość łatwo. Następujący test przechodzi z Grails 2.3.9 ...

Klasa domeny:

// grails-app/domain/com/demo/Person.groovy 
package com.demo 

class Person { 
    String title 
} 

Config.groovy:

// grails-app/conf/Config.groovy 
grails.databinding.convertEmptyStringsToNull = false 

// ... 

Test jednostkowy:

// test/unit/com/demo/PersonSpec.groovy 
package com.demo 

import grails.test.mixin.TestFor 
import spock.lang.Specification 

@TestFor(Person) 
@TestMixin(grails.test.mixin.web.ControllerUnitTestMixin) 
class PersonSpec extends Specification { 

    void "test empty string conversion"() { 
     when: 
     def p = new Person(title: '') 

     then: 
     p.title == '' 
    } 
} 

klucz jest zastosowanie ContollerUnitTestMixin do przypadku testowego, nawet jeśli tak naprawdę nie jest testowanie kontrolera. Zobacz https://jira.grails.org/browse/GRAILS-11136.

Mam nadzieję, że to pomaga.

+0

Tak, test kończy się po dodaniu '@TestMixin (grails.test.mixin.web.ControllerUnitTestMixin)'. – user3737977

+0

to właśnie rozwiązało dla mnie ogromny problem, niezbyt pod wrażeniem grails na tym, tyle konfiguracji i dziwne domyślne zachowanie w tym! tak dzięki! – soheildb

+0

@soheildb "Tak wiele konfiguracji i dziwne domyślne zachowanie w tym" - Jeśli masz zalecenia dotyczące lepszego domyślnego zachowania, proszę złożyć wniosek na https://github.com/grails/grails-core/issues, a my spojrzymy . –

0

Konwersja pustych łańcuchów na wartość null jest cechą wiązania danych Grails, więc stanie się to wszędzie tam, gdzie używane jest wiązanie danych. Jednym z takich miejsc jest wywołanie konstruktora klasy domeny z argumentem mapy. Jeśli nie chcesz, aby łańcuch zostanie zamienione na null, spróbuj tego:

new Todo().priority = ''