【问题标题】:Grails Unit Testing with Composite Keys使用复合键的 Grails 单元测试
【发布时间】:2015-03-23 21:37:58
【问题描述】:

我正在尝试对将具有复合键的对象插入数据库的方法进行单元测试。每当我为此运行单元测试时,我都会得到以下信息。

Failure:  |
testTransaction(com.myapp.foo.TestServiceSpec)
 |
Condition not satisfied:

Transaction.count() == 1
            |       |
            0       false

    at com.myapp.foo.TestServiceSpec.testTransaction(TestServiceSpec.groovy:166)

如果我从我的域类中删除复合键代码而不是其他任何内容,则测试通过。

这是我的域类,Transaction.groovy:

class Transaction implements Serializable {
    String timestamp
    String source
    String tableName
    String fieldName
    Integer changeNumber
    String fieldValue
    String objectId

    static mapping = {
        id composite: ["timestamp", "source", "tableName", "fieldName", "changeNumber"], generator: 'assigned'
    }

    boolean equals(other) {
        if (!(other instanceof Transaction)) {
            return false
        }

        other.timestamp == timestamp && other.source == source && other.id == id && other.tableName == tableName && other.fieldName == fieldName && other.changeNumber == changeNumber
    }

    int hashCode() {
        def builder = new HashCodeBuilder()
        builder.append timestamp
        builder.append source
        builder.append tableName
        builder.append fieldName
        builder.append changeNumber
        builder.toHashCode()
    }
}

这是正在测试的代码:

def response = [code: 'OK']
def transaction = new Transaction()

transaction.timestamp  = (new Date()).format("yyyy-MM-dd HH:mm:ss.SSS")
transaction.source       = "APP"
transaction.tableName    = "TABLE_NAME"
transaction.fieldName    = "FIELD_NAME"
transaction.fieldValue   = "FIELD_VALUE"
transaction.objectId     = "OBJECT_ID"

def changeNumber = Transaction.createCriteria().get {
    eq("objid", currentTransaction.objid)
    eq("tableName", currentTransaction.tableName)
    projections {
        max("changeNumber")
    }
}

currentTransaction.changeNumber = (changeNumber ?: 0) + 1

if(!transaction.save()) {
    transaction.errors.each {
        println it
    }

    response = [code: 'error transaction', status: 500]
}

return response

最后,这是我的单元测试代码:

void testTransaction() {
    when:
    def response = testService.loadTransaction() // Creates transaction row

    then:
    assert response == [code: 'OK']
    assert Transaction.count() == 1
}

域结构是由另一方定义的,我不能以任何方式更改它,所以复合键是必须的。不幸的是,这个应用程序中的许多类都使用复合键,所以如果我不能对它们进行单元测试,我的很多代码就无法被单元测试覆盖。任何能让我朝着正确方向前进的信息都会很棒。

【问题讨论】:

    标签: unit-testing grails grails-orm composite-key


    【解决方案1】:

    不要使用单元测试来测试持久性。

    单元测试有一个 GORM 实现,但它没有数据库支持,只有 ConcurrentHashMap。它非常好,但它只能用于避免在对控制器等其他工件类型进行单元测试时模拟持久层。如果要测试持久性,请使用数据库。

    否则,您会看到像这样的时髦问题,以及类似的问题,例如误报或更糟 - 测试通过但不应该通过的误报,从而在“经过良好测试”的代码中留下错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-25
      • 1970-01-01
      相关资源
      最近更新 更多