2

クライアントから受信した JSON にすべての必須フィールドが含まれていることを確認するテストを Grails で作成しています。マップは次のようになります。

def map = [
    customer: [
        firstName: 'John',
        lastName: 'Doe',
        id: '123',
    ],
    orderNumber: '123456',
    paymentInfo: [
        type: 'paypal',
        amount: '1200',
        currency: 'USD'
    ]
]

言い換えれば、customerpaymentInfoキーはサブキーを持つマップそのものです。

私のテストでは、各キーとサブキーを削除して、入力の検証が機能していることを確認したいと思います。私はこのようなことをしました:

// test 1
map.remove('orderNumber')
def result = service.performAction(map)
assert result == ServiceCall.ValidationError

// test 2
map.remove('customer.firstName')
def result = service.performAction(map)
assert result == ServiceCall.ValidationError

テスト 1 は機能し、キーを適切に削除しますが、テスト 2 はサブキーorderNumberを削除しません。firstName使用できることはわかっておりmap.customer.remove(firstName)、サブキーを適切に削除しますが、文字列の配列を渡すだけでキーとサブキーが適切に削除されるように、テストを十分に汎用的にしようとしています。

def array = ['orderNumber', 'customer.firstName', 'customer.lastName', etc...]

array.each {
    map.remove(it)
    def result = service.performAction(map)
    assert result == ServiceCall.ValidationError
}

この方法でサブキーを削除することはできますか?もしそうなら、どうすればよいですか?

4

1 に答える 1

2

残念ながら、「customer.firstName」はトップレベルマップのキーではないため、機能しません。代わりに、渡したキーを解析するために何かを行うことができます。

これを試して?

array.each {
   def levels = it.tokenize('.')
   if ( levels.size() == 1 ) {
      map.remove(levels[0])
   } else if ( level.size() == 2 ) {
      map.get(levels[0]).remove(levels[1])
   } // else etc.
   def result = service.performAction(map)
   assert result == ServiceCall.ValidationError
}

注意してください、私はこれを非常に非ジェネリックな深さで作成しました...あなたは簡単にジェネリック関数を書いてn番目のレベルのマッププロパティを削除することができます。しかし、2つまたは3つだけ深くする必要があることがわかっている場合は、このようなものは、読みにくいジェネリックコードがなくても問題なく機能するはずです。

どうしてもそれを任意の深さのサブマップで機能させるという問題を乗り越えたい場合は、次のようにします。

array.each {
   def levels = it.tokenize('.')
   if ( levels.size() == 1 ) {
      map.remove(levels[0])
   } else  {
      def ref = map
      levels[0..-2].each {
          ref = ref[it]
      }
      ref.remove(levels[-1])
   }
   def result = service.performAction(map)
   assert result == ServiceCall.ValidationError
}

テストの合間に「マップ」が復元されないことに気づきました...元のテストでもこれが行われなかったため、私のコードは同じように動作します。

于 2013-03-12T03:22:20.337 に答える