使用捕获和模拟对类进行单元测试



我正在尝试对以下类进行单元测试:

class UserProfileDetailsAnalyticUseCaseImp @Inject constructor(private val analyticsProvider: AnalyticsProvider) : UserProfileDetailsAnalyticUseCase {
override fun execute(cdsCustomer: CDSCustomer) {
with(analyticsProvider) {
log(AnalyticEvent.UserId(cdsCustomer.id.toString()))
log(AnalyticEvent.UserEmail(cdsCustomer.email))
}
}
}

这是我的单元测试:

class UserProfileDetailsAnalyticUseCaseImpTest {
private lateinit var userProfileDetailsAnalyticUseCaseImp: UserProfileDetailsAnalyticUseCaseImp
private val analyticsProviders: AnalyticsProvider = mock()

@Before
fun setUp() {
userProfileDetailsAnalyticUseCaseImp = UserProfileDetailsAnalyticUseCaseImp(analyticsProviders)
}
@Test
fun `should send analytic event`() {
// Arrange
val cdsCustomer = CDSCustomer(
id = Random.nextInt(0, 100000),
email = UUID.randomUUID().toString())
val userIdCapture= argumentCaptor<AnalyticEvent.UserId>()
val userEmailCapture= argumentCaptor<AnalyticEvent.UserEmail>()
// Act
userProfileDetailsAnalyticUseCaseImp.execute(cdsCustomer)
// Assert
verify(analyticsProviders, atLeastOnce()).log(userIdCapture.capture())
verify(analyticsProviders, atLeastOnce()).log(userEmailCapture.capture())

assertThat(userIdCapture.firstValue.userId).isEqualTo(cdsCustomer.id.toString())
assertThat(userEmailCapture.firstValue.email).isEqualTo(cdsCustomer.email)
}
}

我得到的错误如下:

AnalyticEvent$UserId cannot be cast to AnalyticEvent$UserEmail

我怀疑,因为被测试的类正在为每个log方法创建一个新对象,所以它们对于单元测试中的已验证方法将不相同

log(AnalyticEvent.UserId(cdsCustomer.id.toString()))

由于将创建一个新的AnaltyicEvent.UserId,并且仅用于相同的AnalyticProvider模拟

非常感谢的任何建议

ArgumentCaptor的文档中,我们可以阅读到:

此实用程序类不进行任何类型检查。泛型签名只是为了避免代码中的强制转换。

此外,用于收集捕获参数的CapturingMatcher有一个匹配所有对象的方法:

public boolean matches(Object argument) {
return true;
}

这意味着这是正常的行为,即使我们指定了捕获器的具体类型,它也会记录所有传递的参数。当然,所有这些参数都必须从同一个基类继承,因为在其他情况下capture方法会导致编译错误。

所以,两个绑架你的人都记录了两个论点。

要修复测试的类强制转换异常,您可以为电子邮件断言secondValue

assertThat(userEmailCapture.secondValue.email).isEqualTo(cdsCustomer.email) 

您也可以停止使用参数捕获器,只需验证log方法的调用。

verify(analyticsProviders).log(AnalyticEvent.UserId(cdsCustomer.id.toString()))
verify(analyticsProviders).log(AnalyticEvent.UserEmail(cdsCustomer.email))

最新更新