Android используйте android .graphics.Matrix в модульном тесте - PullRequest
0 голосов
/ 09 июля 2020

Есть ли способ использовать android .graphics.Matrix в локальном модульном тесте для Android. Когда я пытаюсь использовать объект матрицы, я получаю сообщение об ошибке: java .lang.RuntimeException: метод getValues ​​в android .graphics.Matrix не издевается.

Я подозреваю, что, поскольку класс 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
    }

Это хорошо работает в некоторых случаях, например, когда мне нужно использовать его как фиктивный объект, но когда мне нужно это сделать фактических преобразований с ним или точки карты, нет способа достичь этого с помощью фиктивного объекта.

Теперь я провел свой тест, используя Instrumented Test, поскольку он использует эмулятор и, таким образом, он имеет доступ к встроенным методам, встроенным в Android ОС, но этот тип тестов намного медленнее, чем локальные модульные тесты. Мой вопрос: есть ли способ создать локальный модульный тест, который делает доступным использование класса Matrix?

1 Ответ

0 голосов
/ 09 июля 2020
  1. Используйте Robolectri c. Это обеспечит реализацию Matrix, которая может работать на локальной JVM, поэтому вам не придется использовать свои собственные макеты. Обратной стороной использования Robolectri c является то, что вы тестируете реализацию Robolectri c SDK Android, которая может совпадать или не соответствовать фактическому коду, который выполняется на реальном устройстве. Тем не менее, Robolectri c существует уже некоторое время и поддерживается Google, поэтому его использование должно быть безопасным.

  2. Абстрагирование Matrix вдали от вашего кода. Мокинг типов, которыми вы не владеете, в целом не является хорошей практикой, так как вы неизбежно будете делать предположения о реализации этого типа, которые могут или не могут выполняться, когда вы работаете с фактической реализацией. Создание тестовых двойников для ваших собственных типов безопасно, так как вы контролируете поведение. Я бы предложил создать тонкую оболочку поверх Matrix, которую вы можете имитировать / подделывать в своих тестах и ​​которая сама по себе не требует модульных тестов.

...