2012-01-30 6 views
4

У меня есть пользовательский тег lib, который я написал, чтобы я мог легко отображать свойства объекта. Это позволяет мне позвонитьGrails 2.0 Unit Testing Custom Tag Lib

<g:property label="Name" property="${user.name}"/> 

который держит мои взгляды коротким и последовательным, а также позволяет мне быстро вносить изменения. Мой код taglib выглядит следующим образом:

def property = {attrs, body -> 
    def startingHtml = "..." 
    def endingHtml = "..." 

    out << startingHtml 
    renderField(attrs.property) 
    out << endingHtml 
} 

def renderField(property) { 
    if (property instanceof Collection) { 
     property.each { out << it + "</br>" } 
    } else if(property instanceof Address){ 
     renderAddress(property) 
    } else { 
     out << property 
    } 
} 

def renderAddress(address) { 
    out << "Address Render Logic Here" 
} 

Я пытаюсь добавить некоторые модульные тесты вокруг этого кода, потому что в нем есть логика. Используя приведенные здесь примеры (http://grails.org/doc/latest/guide/testing.html#unitTestingTagLibraries) Я начал добавлять некоторые тесты. Первые два сценария, которые обрабатываются моим тегом, это String and Collection, которые я смог проверить правильно (первые два теста ниже). Последним сценарием, который мне нужно проверить, является объект Address (который является только POGO со строковыми атрибутами). Я не могу найти способ проверить передачу объекта в качестве атрибута в тег lib.

@TestFor(PropertyTagLib) 
class PropertyTagLibTests { 

@Test 
void propertyTagShouldRenderPropertyInsideOfTDWhenPropertyIsAString() { 
    String result = applyTemplate('<g:property label="something" property="someTextValue"/>').trim() 

    assert result.contains('someTextValue') 
} 

@Test 
void propertyTagShouldRenderList() { 
    String result = applyTemplate('g:property label="something" property="[\"one\", \"two\", \"three\"]"/>').trim() 

    assert result.contains("one</br>two</br>three</br>") 
} 

@Test 
void propertyTagShouldRenderPropertyInsideOfTDWhenPropertyIsAnAddress() { 
    def address = new Address(line1: "Line 1") 
    String result = applyTemplate('<g:property label="something" property="${address}"/>').trim() 

    assert result.contains("Address Render Logic Here") 
} 
} 

Как я могу проверить свой taglib, когда один из атрибутов является объектом?

+0

Не уверен, что на этом, я думаю. Мой оригинальный ответ был просто опасным, но у меня нет никаких предложений за его пределами:/ –

ответ

0

Таким образом, я решил это путем «вырезания среднего человека» и обхода applyTemplate() и непосредственно перехода к методу, который выполняет логику. Это не совсем идеально по двум причинам: 1) Я не утверждаю, что тег свойства подключен с помощью renderField, но, надеюсь, мои другие тесты, которые все еще используют applyTemplate(), гарантируют это. 2) В реальном мире out в TagLib является производителем вывода, и в моем тесте я создал его как список (я могу сделать это, так как все, что вы можете сделать, сдвиг влево будет достаточным).

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

@Test 
void renderFieldShouldRenderAddress() { 
    def address = new Address(line1: "Line 1", line2: "Line 2", line3: "Line 3", 
     city: "City", state: "ST", zipCode: "12345", country: "USA", 
     buildingNumber: null, buildingName: null, roomNumber: null 
     ) 
    def tagLib = new PropertyTagLib() 
    def results = [] 
    tagLib.metaClass.getOut = { 
     results 
    } 

    tagLib.renderField(address) 

    assert "Line 1" == results[0] 
    assert "<br />" == results[1] 
    assert "Line 2" == results[2] 
    assert "<br />" == results[3] 
    assert "Line 3" == results[4] 
    assert "<br />" == results[5] 
    assert "City, ST 12345" == results[6] 
    assert "<br />" == results[7] 
    assert "USA" == results[8] 
    assert "<br />" == results[9] 
    assert 10 == results.size() 
} 

Любые мысли?

7

Декларация ApplyTemplate() выглядит следующим образом:

String applyTemplate(String contents, Map model = [:]) 

параметры тега передаются через model.

Ваш тест может выглядеть следующим образом:

@Test 
void propertyTagShouldRenderPropertyInsideOfTDWhenPropertyIsAnAddress() { 
    String result = applyTemplate('<g:property label="something" property="${address}"/>', [address : new Address(line1: "Line 1")]).trim() 

    assert result.contains("Address Render Logic Here") 
} 
+0

Все отмечают одинарные кавычки в строке, переданной в applyTemplate, если вы этого не сделаете, вам нужно будет избежать $ –