0

私が持っているメソッドの spock を使用してテストを作成しようとしています。

メソッドは次のようになります-

InvoiceView getInvoiceDetailView(String invoiceNumber, Boolean isNew) {
    InvoiceView detailView;
    if (isNew) {
        newInvoiceDao.em = billingEm;
        //call InvoiceDao
        List<GroovyRowResult> invoiceSummaryRowResult = billingAdmin.rows(InvoiceQueries.GET_NEW_INVOICE_SUMMARIES_BY_NUMBER, [invoiceNumber:invoiceNumber]);
        List<GroovyRowResult> invoiceDetailsRowResult = billingAdmin.rows(InvoiceQueries.GET_NEW_INVOICE_DETAILS_BY_NUMBER, [invoiceNumber:invoiceNumber]);
        InvoiceModel invoiceModel = newInvoiceDao.getInvoice(invoiceNumber);
        detailView = new InvoiceView(invoice:invoiceModel,
                                             summary:invoiceSummaryRowResult,
                                            details:invoiceDetailsRowResult);
} ...

私のテストは、 isNew パラメータの値として渡された true でこのメソッドが呼び出されると、有効な InvoiceView オブジェクトが返されることをアサートしようとしているだけです。

私の spock テストでは、メソッドから返されると予想されるいくつかのオブジェクトを作成します。

def expectedInvoiceModel = new InvoiceModel()
def expectedInvoiceSummaryRowResult = new ArrayList<GroovyRowResult>()
def expectedInvoiceDetailsRowResult = new ArrayList<GroovyRowResult>()

def expectedInvoiceView = new InvoiceView(invoice:expectedInvoiceModel,
                                          summary:expectedInvoiceSummaryRowResult,
                                          details:expectedInvoiceDetailsRowResult)

また、呼び出し先の dao オブジェクトをモックします。

def setup() {
    ...
    service.billingAdmin = Mock(Sql)
    ...
}

最後に Spock フィクスチャに取り掛かります。問題のある比較行をコメントアウトし、回避策を講じています。私の質問は、「then」ブロックの最初の行が失敗するのはなぜですか?

def "getInvoiceDetailView returns valid InvoiceView for new invoice"() {
    given:
        service.billingAdmin.rows(InvoiceQueries.GET_NEW_INVOICE_SUMMARIES_BY_NUMBER, [invoiceNumber:invoiceNumber]) >> expectedInvoiceSummaryRowResult
        service.billingAdmin.rows(InvoiceQueries.GET_NEW_INVOICE_DETAILS_BY_NUMBER, [invoiceNumber:invoiceNumber]) >> expectedInvoiceDetailsRowResult
        service.newInvoiceDao.getInvoice(_) >> expectedInvoiceModel

    when:
        def result = service.getInvoiceDetailView(invoiceNumber, true)
    then:
        //result == expectedInvoiceView -- Why doesn't this work?
        result.invoice == expectedInvoiceModel
        result.summary == expectedInvoiceSummaryRowResult
        result.details == expectedInvoiceDetailsRowResult
}
4

2 に答える 2

2

どうやら、オブジェクトはequalsクラスのメソッドに従って等しくありませんInvoiceView。または、そのクラスがequalsメソッドを宣言しておらず、オブジェクトが同一ではない可能性があります(のようにObject.equals)。

于 2012-11-12T21:17:28.357 に答える
0

ザカリー。

getInvoice メソッドを正しくモックしていません。2 つのパラメーターを渡して呼び出しますが、模擬呼び出しは 1 つだけを想定しています (「_」文字は任意のパラメーターを受け入れますが、正確に 1 つと一致します)。モック化されたメソッドが一致しないため、getInvoice の呼び出しはデフォルト値の null を返し、テストは失敗します。

テストに合格するには、次のことを行う必要があります。

service.newInvoiceDao.getInvoice(_, _) >> expectedInvoiceModel

それをより明確にするために、小さなテストを書きました。次のクラスがあるとします。

private static class StringUtils {
    public String concatenate(String a, String b) {
        return a + b;
    }
}

次のテストは失敗します。

def "concatenation should work!"() {
    given: 
    StringUtils su = Mock()
    su.concatenate(_) >> "ab"

    when:
    def result = su.concatenate("a", "b")

    then:
    result == "ab" 
}

私のモックされたメソッドは、1 つのパラメーターのみを想定していることに注意してください。

su.concatenate(_) >> "ab"

これは、null 値が返されたことを示すエラー メッセージです。

Condition not satisfied:

result == "ab"
|      |
null   false

ただし、連結メソッドを適切にモックすると、テストは成功します。

su.concatenate(_, _) >> "ab"
于 2012-11-13T14:49:54.713 に答える