spock:unit test 对于graphic2d和BuffreImage

yqkkidmi  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(364)

我很难测试下面的类。如何编写一个测试来检查图形是否以特定的宽度、高度绘制“name”,以及使用spock对下面的类编写哪些其他测试。我怎么能嘲笑这个例外呢?

class NameCardCreator{

       private val bufferedImage = BufferedImage(580, 380, BufferedImage.TYPE_INT_ARGB)
        var name: String? = null
        const val DISCLAIMER = "Name is Correct"
        fun createNameCard(): String?
        {
            var generic64: String? = null
            try {
                dashed = BasicStroke(3f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0f, floatArrayOf(5f), 0f)
                val graphics =  bufferedImage.createGraphics()
                graphics.drawRoundRect(20, 20, 535, 340, 15, 15) //actual card size
                val fontMetrics = graphics.fontMetrics
                graphics.drawLine(300, 120, 540, 120)
                if (!name.isNullOrEmpty()) {
                    graphics.drawString(name, 300, 110)
                }
                graphics.drawString(DISCLAIMER, 50, 290)
                generic64 = toBase64(bufferedImage)
                return generic64
            } catch (ie: IOException) {
                logger.info("Name card could not be generated $ie.message")
            }
            return generic64
        }

        protected fun toBase64(bufferedImage: BufferedImage): String? {
            var base64Str: String? = null
            var os: ByteArrayOutputStream? = null
            var b64: OutputStream? = null
            try {
                os = ByteArrayOutputStream()
                b64 = Base64OutputStream(os)
                ImageIO.write(bufferedImage, "png", b64)
                base64Str = os.toString("UTF-8")
            } catch (e: Exception) {
                logger.error(e.message)
            } finally {
                os?.close()
                b64?.close()
            }
            return base64Str
        }
    }
83qze16e

83qze16e1#

我不会说kotlin,但我对您的类做了一些研究,只是添加了一个单独的构造函数,您可以在其中注入 BufferedImage . 一旦你能做到这一点,你也可以注入一个模拟。如果你存根 createGraphics() 在那嘲弄中又回到了另一个 Graphics2D mock,您可以轻松验证 graphics.drawString(name, 300, 110) 是用你期望的名字叫的。
再说,也没必要抓什么 IOExceptioncreateNameCard() 因为在 toBase64() 您可以捕获所有异常。所以要么你完全去掉试扣 createNameCard() (变体a)或删除中的catch子句 toBase64() ,使您可以在调用方法中捕获一些内容(变量b)。
无论如何,我保留了两个catch块,并向您展示了如何获得整个文件的100%测试覆盖率,包括错误情况:

package de.scrum_master.testing.kotlin

import org.apache.commons.codec.binary.Base64OutputStream
import java.awt.BasicStroke
import java.awt.image.BufferedImage
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.OutputStream
import javax.imageio.ImageIO

class NameCardCreator {
  private var bufferedImage = BufferedImage(580, 380, BufferedImage.TYPE_INT_ARGB)
  private var name: String? = null
  val DISCLAIMER = "Name is Correct"

  constructor()

  constructor(name: String?) {
    this.name = name
  }

  constructor(bufferedImage: BufferedImage, name: String?) {
    this.bufferedImage = bufferedImage
    this.name = name
  }

  fun createNameCard(): String? {
    var generic64: String? = null
    try {
      val dashed = BasicStroke(3f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0f, floatArrayOf(5f), 0f)
      val graphics = bufferedImage.createGraphics()
      graphics.drawRoundRect(20, 20, 535, 340, 15, 15) // actual card size
      val fontMetrics = graphics.fontMetrics
      graphics.drawLine(300, 120, 540, 120)
      if (!name.isNullOrEmpty()) {
        graphics.drawString(name, 300, 110)
      }
      graphics.drawString(DISCLAIMER, 50, 290)
      generic64 = toBase64(bufferedImage)
      return generic64
    } catch (ie: IOException) {
      println("Name card could not be generated: $ie.message")
    }
    return generic64
  }

  protected fun toBase64(bufferedImage: BufferedImage): String? {
    var base64Str: String? = null
    var os: ByteArrayOutputStream? = null
    var b64: OutputStream? = null
    try {
      os = ByteArrayOutputStream()
      b64 = Base64OutputStream(os)
      ImageIO.write(bufferedImage, "png", b64)
      base64Str = os.toString("UTF-8")
    } catch (e: Exception) {
      println("Base64 encoding failed: $e.message")
    } finally {
      os?.close()
      b64?.close()
    }
    return base64Str
  }

}
package de.scrum_master.testing.kotlin

import org.apache.commons.codec.binary.Base64
import spock.lang.Specification

import javax.imageio.ImageIO
import java.awt.*
import java.awt.image.BufferedImage

class NameCardCreatorTest extends Specification {
  def "check that base64 actually encodes an image"() {
    given:
    def nameCardCreator = new NameCardCreator("John Doe")

    when:
    def imageBase64 = nameCardCreator.createNameCard()
//    println imageBase64
    def imageBytes = new Base64().decode(imageBase64)
//    new FileOutputStream("name-card.png").write(imageBytes)
    def bufferedImage = ImageIO.read(new ByteArrayInputStream(imageBytes))

    then:
    bufferedImage.width == 580
    bufferedImage.height == 380
  }

  def "check that name was written on card"() {
    given:
    def graphics2D = Mock(Graphics2D)
    def bufferedImage = Mock(BufferedImage) {
      // Return Graphics2D mock
      createGraphics() >> graphics2D
    }
    when:
    new NameCardCreator(bufferedImage, "John Doe").createNameCard()

    then:
    1 * graphics2D.drawString("John Doe", _, _)
  }

  def "exception during card creation leads to null result"() {
    given:
    def bufferedImage = Mock(BufferedImage) {
      // Throw an exception for each method call
      _(*_) >> { throw new IOException("uh-oh") }
    }
    expect:
    new NameCardCreator(bufferedImage, "John Doe").createNameCard() == null
  }

  def "exception during base64 encoding leads to null result"() {
    given:
    def bufferedImage = Mock(BufferedImage) {
      // Throw an exception for each method call
      _(*_) >> { throw new IOException("uh-oh") }
    }

    expect:
    new NameCardCreator().toBase64(bufferedImage) == null
  }
}

相关问题