繁体   English   中英

Spock:Graphic2d 和 BuffredImage 的单元测试

[英]Spock:Unit Test for Graphic2d and BuffredImage

我在如何测试下面的 class 时遇到了困难。如何编写一个测试来检查图形是否以特定的宽度、高度绘制“名称”?以及我可以使用 spock 针对以下 class 编写哪些其他测试。 以及如何模拟异常?

 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
        }
    }

我不会说 Kotlin,但我玩了一下你的 class 并添加了一个单独的构造函数,你可以在其中注入一个BufferedImage 只要你能做到这一点,你也可以注入一个模拟。 如果您在该模拟中存根createGraphics()以返回另一个Graphics2D模拟,则可以轻松验证是否使用您期望的名称调用了graphics.drawString(name, 300, 110)

此外,不需要在createNameCard()中捕获任何IOException ,因为在toBase64()中您会捕获所有异常。 因此,要么完全删除createNameCard()中的 try-catch (变体 A),要么删除toBase64()中的 catch 子句,从而在调用方法(变体 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
  }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM