我正在为一个函数编写 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/