java - 在函数中模拟私有(private)变量以测试 Junit4

标签 java android unit-testing kotlin junit

我正在为一个函数编写 Junit4 测试,该函数具有基于其他函数设置的 boolean 变量。如何在我的测试用例中模拟这些 boolean 变量。

我正在测试的功能

private var operatorSigned = false
private var engineerSigned = false


override fun onValidationSucceeded() {
    if (operatorSigned && engineerSigned) {
        sendQualityControlCheck()
    } else {
        view.showToastMessage(app.getString(R.string.quality_control_signatures_not_complete))
    }
}

这就是设置值的方式

override fun signatureSigned(name: String, svgSignature: String, bitmapSignature: Bitmap, signatureType: SignatureType) {
    val svgSignatureGzipped = CompressionTools.gzipCompress(svgSignature)
    when (signatureType) {
        SignatureType.OPERATOR -> {
            operatorSignature = QualityControlSignature(svgSignatureGzipped, DateTime())
            operatorSigned = true
            view.operatorSignatureSigned()
        }
        SignatureType.ENGINEER -> {
            engineerSignature = QualityControlSignature(svgSignatureGzipped, DateTime())
            engineerSigned = true
            engineerName = name
            view.engineerSignatureSigned()
        }
    }
}

我的测试用例

@Test
fun `must show toast message when onValidationSucceeded is called and operatorSigned is false`() {
    `when`(app.getString(R.string.quality_control_signatures_not_complete)).thenReturn("Operator and Engineer signature required")
    presenter.onValidationSucceeded()
    verify(view).showToastMessage("Operator and Engineer signature required")
}

我希望能够更改operatorSigned 和engineerSigned 上的值,我该怎么做。

最佳答案

让我们假设代码的 OPERATOR 路径将这些 boolean 值设置为 false:

@Test
fun `must show toast message when onValidationSucceeded is called and signature is Operator`() {
    // Given
    signatureSigned("unusedName", "unusedSig", null, SignatureType.OPERATOR) 
`when`(app.getString(R.string.quality_control_signatures_not_complete)).thenReturn("Operator and Engineer signature required")
    // When
    presenter.onValidationSucceeded()
    // Then
    verify(view).showToastMessage("Operator and Engineer signature required")
}

(必须假装,因为现在您共享的代码仅将 boolean 值设置为 true)。

您现在正在对类行为进行单元测试,而不是测试该行为的编码方式。例如,现在如果将这些 boolean 值重构为 Int 值。这个测试仍然会通过,而无需您触摸它,这是一件好事!


或者如果您的代码保持原样。您可以这样测试:

@Test
fun `must show toast message when onValidationSucceeded is called and has not been signature signed`() {
    // Given
    // We haven't signature signed (see verify)
   `when`(app.getString(R.string.quality_control_signatures_not_complete)).thenReturn("Operator and Engineer signature required")
    // When
    presenter.onValidationSucceeded()
    // Then
    verify(view).showToastMessage("Operator and Engineer signature required")
    verify(view, never()).operatorSignatureSigned()
    verify(view, never()).engineerSignatureSigned()
}

如何模拟静态方法(提示您不这样做,您可以将其移至系统边缘并稍后再担心)。

您现在的类(class):

class MyClass {

    override fun signatureSigned(name: String, svgSignature: String, bitmapSignature: Bitmap, signatureType: SignatureType) {
        val svgSignatureGzipped = CompressionTools.gzipCompress(svgSignature)
        ...
    }

}

因此,您需要删除静态调用,以便另一个可以作为依赖项执行静态调用的类。

interface SignatureCompressor {
    fun compress(signature: String)
}

class GZipSignatureCompressor : SignatureCompressor {
    override fun compress(signature: String) {
        return CompressionTools.gzipCompress(signature)
    } 
}

现在你的类变成:

class MyClass(private val compressor: SignatureCompressor) {

    override fun signatureSigned(name: String, svgSignature: String, bitmapSignature: Bitmap, signatureType: SignatureType) {
        val svgSignatureGzipped = compressor.compress(svgSignature)
        ...
    }

}

你可以模拟压缩器:

 val cut = MyClass(mockk())

如果您只有一种压缩实现,则也不需要该接口(interface)

关于java - 在函数中模拟私有(private)变量以测试 Junit4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60211478/

相关文章:

java - 在 Mockito 中捕获一个参数

c# - 更改生成的单元测试文件的目录

Java - 从服务器再次向客户端请求密码

java - URLEncode处理后如何加载图像

java - 通过网络与 Derby 的嵌入式连接有哪些缺陷?

java - Android 线程详细信息

android - 尝试使用 getBytes(Charset) 时为 "VFY: dead code"

android - 如何检索 cameraID 并使用 setTorchMode?

java - 可以对 Windows 环境变量的修改进行单元测试吗?

Android 错误导入引用 R 资源的库