簡體   English   中英

如何編寫用於異常處理的spock測試用例?

[英]How to write spock test case for exception handling?

我正在學習 Spock,所以這可能是非常基礎的。

public Random genRand() {
  try {
    return SecureRandom.getInstanceStrong();
  }
  catch (NoSuchAlgorithmException e) {
    logger.debug(e.getMessage());
    return new SecureRandom();
  }
}

到目前為止我嘗試過的是:

public void setup() {
  mockClassName = spy(ClassName)
  mockClassName.logger() >> mockLogger
}

def "exception test case"() {
  given: "nothing"

  when:"method call happens"
  mockClassName.genRand()

  then:"handle"
  SecureRandom.getInstanceStrong()
}

這僅涵蓋 try 塊。

嘗試時:

public void setup() {
  mockClassName = spy(ClassName)
  mockClassName.logger() >> mockLogger
}

def "exception test case"() {
  given: "nothing"
  SecureRandom.getInstanceStrong() >> Exception

  when:"method call happens"
  mockClassName.genRand()

  then:"catch"
  NoSuchAlgorithmException e = thrown()
  new SecureRandom()
}

這給出了錯誤,類型為java.security.NoSuchAlgorithmException的預期異常,但沒有拋出異常。

是否可以在一個測試用例中同時進行 try 和 catch? 隨意做兩個。

是否可以在一個測試用例中同時進行 try 和 catch?

不是真的,不是問題所問的方式。 您可以同時測試兩者,但這些將是不同的情況,因為它們與代碼中的不同路徑相關聯。

您不應該嘗試在一次測試中測試代碼的多個分支,因此在兩次測試中進行測試實際上是正確的方法。 如果您試圖找到對您的測試的簡單描述並且必須描述幾種結果,那么這暗示您的方法不好。

提醒一下,你應該用“It...”命名你的測試方法,例如:

“如果找不到 SecureRandom 的強實例,它會返回一個默認的 SecureRandom”

另一點:您的代碼永遠不會將NoSuchAlgorithmException泄漏到 Spec 中。 此異常在您的生產代碼中被捕獲,然后您返回一個有效的SecureRandom 如果您的代碼確實拋出異常,則只能使用thrown() ,這意味着這是一個艱難的期望。 如果沒有拋出異常,您的測試將失敗。

引用我自己的評論:

您為什么不想更改應用程序代碼以使其更易於測試? 您可以將SecureRandom.getInstanceStrong()調用分解為一個額外的方法,從genRand()調用它,像以前一樣處理那里的異常。 然后,您可以將該方法存入一個用於錯誤情況的間諜程序中,拋出異常而不是返回結果。 這將使您完全覆蓋所有執行路徑,而無需模擬 JDK 類的靜態方法。

我的意思是這樣的:

package de.scrum_master.stackoverflow.q74797317;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

public class RandomProvider {
  public Random genRand() {
    try {
      return getRandStrong();
    }
    catch (NoSuchAlgorithmException e) {
      System.err.println(e.getMessage());
      return new SecureRandom();
    }
  }

  protected SecureRandom getRandStrong() throws NoSuchAlgorithmException {
    return SecureRandom.getInstanceStrong();
  }
}
package de.scrum_master.stackoverflow.q74797317

import spock.lang.Specification

import java.security.NoSuchAlgorithmException

class RandomProviderTest extends Specification {
  def "happy path"() {
    given:
    RandomProvider randomProvider = new RandomProvider()

    expect:
    randomProvider.genRand()
  }

  def "exception test case"() {
    given:
    RandomProvider randomProvider = Spy() {
      getRandStrong() >> { throw new NoSuchAlgorithmException("oops") }
    }

    expect:
    randomProvider.genRand()
  }
}

Groovy Web 控制台中嘗試一下。

在我的 IDE 中,覆蓋視圖如下所示:

覆蓋率報告

突出顯示覆蓋方法的被測類

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM