简体   繁体   English

Grails 2.0单元测试自定义标签库

[英]Grails 2.0 Unit Testing Custom Tag Lib

I have a custom tag lib that I wrote so that I can display properties of an object in an easy fashion. 我有一个我编写的自定义标记库,以便我可以轻松地显示对象的属性。 It allows me to call 它允许我打电话

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

Which keeps my views short and consistent as well as allows me to make changes quickly. 这使我的观点简短而一致,并允许我快速进行更改。 My taglib code is as follows: 我的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"
}

I'm trying to add some unit tests around this code because there is logic in it. 我试图在这段代码中添加一些单元测试,因为它有逻辑。 Using the examples found here ( http://grails.org/doc/latest/guide/testing.html#unitTestingTagLibraries ) I started adding some tests. 使用此处的示例( http://grails.org/doc/latest/guide/testing.html#unitTestingTagLibraries ),我开始添加一些测试。 The first two scenarios that my tag currently handles are String and Collection, which I was able to test correctly (first two tests below). 我的标签当前处理的前两个场景是String和Collection,我能够正确测试(下面的前两个测试)。 The last scenario that I need to test is an Address object (which is just a POGO with String attributes). 我需要测试的最后一个场景是Address对象(它只是一个带有String属性的POGO)。 I can't seem to find a way to test passing an object as an attribute into a tag lib. 我似乎无法找到一种方法来测试将对象作为属性传递到标记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")
}
}

How can I test my taglib when one of the attributes is an object? 当其中一个属性是对象时,如何测试我的taglib?

The declaration of applyTemplate() looks as follows: applyTemplate()的声明如下:

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

Tag parameters are passed through model . 标签参数通过model传递。

Your test might look as follows: 您的测试可能如下所示:

@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")
}

So I solved this by "cutting out the middle man" and circumventing the applyTemplate() and directly going to the method that does the logic. 所以我通过“删除中间人”并绕过applyTemplate()并直接转到执行逻辑的方法来解决这个问题。 This isn't quite ideal because of two reasons: 1) I'm not asserting that the property tag is hooked up with renderField, but hopefully my other tests which still use applyTemplate() ensure that. 这不是很理想,原因有两个:1)我没有声明属性标记与renderField连接,但希望我的其他测试仍然使用applyTemplate()确保。 2) In the real world out in a TagLib is a output writer and in my test I've created it as a list (I can do this since anything you can do a left shift on will suffice). 2)在现实世界out ,TagLib是一个输出编写器,在我的测试中我将它创建为一个列表(我可以这样做,因为任何你可以做左移的东西就足够了)。

What I do like about using a list is it helps assert order. 我喜欢使用列表是有助于断言顺序。

@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()
}

Any thoughts? 有什么想法吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM