Android在单元测试中使用Android.graphics.Matrix

Android在单元测试中使用Android.graphics.Matrix,android,unit-testing,kotlin,matrix,Android,Unit Testing,Kotlin,Matrix,是否有一种方法可以在android的本地单元测试中使用android.graphics.Matrix。当我尝试使用matrix对象时,我收到错误消息:java.lang.RuntimeException:Method getValues in android.graphics.matrix not mock。 我怀疑由于Matrix类使用本机方法,这意味着该类不能用于本地单元测试。所以为了使用它,我必须使用Mockito创建一个模拟对象。下面是一个创建模拟对象的示例,该对象始终返回标识矩阵

是否有一种方法可以在android的本地单元测试中使用android.graphics.Matrix。当我尝试使用matrix对象时,我收到错误消息:java.lang.RuntimeException:Method getValues in android.graphics.matrix not mock。

我怀疑由于Matrix类使用本机方法,这意味着该类不能用于本地单元测试。所以为了使用它,我必须使用Mockito创建一个模拟对象。下面是一个创建模拟对象的示例,该对象始终返回标识矩阵

    /**
     * Create Mockito graphic matrix, since the matrix methods are native and are not supported
     * in local unit testing. We need to use Mockito to mock a matrix, that always return the
     * identity matrix, when getValues() method is called. Identity matrix is the default matrix 
     * with no transformations applied to it.
     */
    fun getMockMatrix(): Matrix {

        val mockMatrix = mock(Matrix::class.java)
        doAnswer { invocation ->

            val v = (invocation.arguments[0] as FloatArray)

            // always set values to match the identity matrix, when getValues() method is called
            v[0] = 1f
            v[4] = 1f
            v[8] = 1f

            null
        }.`when`(mockMatrix).getValues(FloatArray(9))

        val matrixValues = FloatArray(9)
        mockMatrix.getValues(matrixValues)

        // check if the mocked matrix matches the identity matrix
        assertArrayEquals(
            matrixValues, floatArrayOf(
                1f, 0f, 0f,
                0f, 1f, 0f,
                0f, 0f, 1f
            )
        )
        return mockMatrix
    }
这在某些情况下很有效,例如当我需要将其用作虚拟对象时,但当我需要使用它或映射点进行实际转换时,无法使用模拟对象来实现

现在我使用
仪器化测试进行测试,因为它使用仿真器,这样它就可以访问Android操作系统中集成的本机方法,但是这些类型的测试比本地单元测试慢得多。我的问题是,是否有办法创建本地单元测试,从而可以使用Matrix类

  • 使用。它将提供一个可以在本地JVM上运行的
    Matrix
    实现,因此您不必使用自己的mock。使用Robolectric的缺点是,您正在测试Robolectric的Android SDK实现,它可能与实际设备上运行的实际代码一致,也可能不一致。这就是说,Robolectric已经存在了一段时间,由谷歌维护,所以使用起来应该是安全的

  • 抽象
    矩阵
    远离您的代码。一般来说,模拟您不拥有的类型不是一个好的实践,因为您不可避免地会对该类型的实现做出假设,而当您在实际实现中运行时,这些假设可能成立,也可能不成立。为您自己的类型创建双重测试是安全的,因为您可以控制行为。我建议的解决方案是在
    Matrix
    上创建一个薄包装,您可以在测试中模拟/伪造它,并且它本身不需要单元测试