Модульное тестирование UICollectionView.indexPath (для: UICollectionViewCell) - PullRequest
0 голосов
/ 13 января 2020

Я пытаюсь выполнить модульное тестирование этого бита кода в ViewController

    func categoryTextEditedAt(_ cell: UICollectionViewCell, _ text: String) {
        guard let indexPath = self.collectionView.indexPath(for: cell), text != "" else {return}

        //Rest of the codes to be tested
    }

. И в моем модульном тесте для проверки вышеуказанной функции используется следующее:

    func testCategoryTextEditedAt() {
        sut.viewDidLoad()
        sut.collectionView.reloadData()
        let cell = sut.collectionView.dataSource?.collectionView(sut.collectionView, cellForItemAt: IndexPath(item: 0, section: 0))
        sut.categoryTextEditedAt(cell!, "testString")
    }

но я продолжаю получать 'ноль' для функции indexPath inside categoryTextEditedAt(:). Во время отладки я обнаружил, что внутри testCategoryTextEditedAt() ячейка имеет значение, но self.collectionView.indexPath(for:cell) продолжает возвращать 'nil' для 'indexPath.'

Как я могу go об этом процессе?

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Для тех, кому интересно, как выполнить модульное тестирование collectionViewDelegateMethod:

    func categoryTextEditedAt(_ cell: UICollectionViewCell, _ text: String) {
        guard let indexPath = self.collectionView.indexPath(for: cell), text != "" else {return}

        //Rest of the codes to be tested
    }

, вы можете сделать что-то вроде

func testCategoryTextEditedAt() {
    class MockCV: UICollectionView {
        override func indexPath(for cell: UICollectionViewCell) -> IndexPath? {
            let anyIndexPathWhichEverYoulike = IndexPath(item:0, section:0)
            return anyIndexPathWhichEverYoulike
        }
    }
    sut.collectionView = MockCV()
    let cell = sut.collectionView.dataSource?.collectionView(sut.collectionView, cellForItemAt: IndexPath(item: 0, section: 0))
    sut.categoryTextEditedAt(cell!, "testString")
}
0 голосов
/ 13 января 2020

Я думаю, ваша проблема в том, что вы пытаетесь протестировать код не в том месте.

Представьте, что если вам нужно протестировать функцию модуля, вам нужно создать экземпляр всей структуры UICollection, это плохо запах.

Например, вы можете сделать это.

enum UseCaseError {
    textEmpty
}

class UseCase {
    private let index: Int
    private let text: String
    init(index: Int, text: String) {
        self.index = index
        self.text = text
    }

    public func execute() throws {
        guard text.isEmpty == false else {
            throw UseCaseError.textEmpty
        }

        // your logic here to be tested
    }
}

Глядя на это UseCase, вы можете проверить, когда text пусто и все ваши бизнес-логи c

Теперь вам просто нужно поместить его в categoryTextEditedAt метод

func categoryTextEditedAt(_ cell: UICollectionViewCell, _ text: String) {
    guard let indexPath = self.collectionView.indexPath(for: cell) { return }
    try? UseCase(index: indexPath.item, text: text).execute()
}

Если вы поместите код отдельно, вы можете проверить его раньше, и вам не нужно тратить время на попытки UIKit функции работают, только ваша логика c.

Я надеюсь помочь вам с этим примером.

...