[英]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.