TableView isSelected Scenario Swift 的单元测试 [英] Unit Test for TableView isSelected Scenario Swift
问题描述
我有一个简单的场景和 tableView.
I have a simple scenario and tableView.
我需要选择 3 个单元格,即使我滚动它也会保持原样.我可以选择 1、2 或 3 个单元格,但不能选择 4 个或更多.当我选择 4 个单元格时,什么都不会发生.如果有 3 个选定的单元格并且我单击其中一个单元格,则应取消选择我选择的单元格.到现在为止还挺好.感谢@vadian 的帮助,我可以实现如下.但是我一整天都在为这个场景写单元测试,但无法处理它..我决定向社区求助,但仍然找不到方法..
I need to select 3 cells and and even I scroll it will be stay like. I can select 1, 2 or 3 cells but not 4 or more.When I select 4 cells nothing should happen. If there are 3 selected cells and I click one of them the cell which I selected should be deselected. So far so good. Thanks to @vadian help I can make this happen as below. But I tried all day writing unit test for this scenario but could not handle it.. I decided to ask help community and still could not find a way..
问题是:对于这种情况,我如何用一种很好的方法编写单元测试?
Question is: How can I write unit test with a nice approach for this scenario ?
/// My Model ///
struct Item: Codable {
let name: String
let image: String
var isSelected = false
enum CodingKeys: String, CodingKey {
case name = "name"
case image = "image"
}
}
// MARK: - UITableViewDelegate
extension ViewController: UITableViewDelegate {
let items = [Item]() // fetched from network, there is item objects inside it.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
items[indexPath.row].isSelected.toggle()
tableView.reloadRows(at: [indexPath], with: .automatic)
}
func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
return items[indexPath.row].isSelected || items.filter{$0.isSelected}.count < 3 ? indexPath : nil
}
}
// MARK: - UITableViewDataSource
extension ItemViewModel: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Food", for: indexPath) as! FoodTableViewCell
let item = self.items[indexPath.row]
cell.isSelected = item.isSelected
return cell
}
}
}
推荐答案
当然,您可以为 tableView 操作编写许多单元测试,但我同意 Matt 在这应该很简单"的观点.您的 ViewModel 需要根据单独关注"进行处理;原则,否则需要重构.我假设您将所有逻辑移到 ViewModel 中,然后您可以编写如下单元测试.
Of course, you can write many unit tests for tableView actions but I agree with Matt in terms of "this should be simple". Your ViewModel needs to be handled according to "Separate Concern" principles otherwise it needs to be refactored. I assume you move all logic into ViewModel then you can write a unit test as below.
import Foundation
class YourViewControllerTest: XCTestCase {
var viewModel: ItemViewModel!
fileprivate var fetcher: MockItemFetcher!
var tableView: UITableView!
override func setUp() {
super.setUp()
fetcher = MockItemFetcher()
viewModel = ItemViewModel(fetchable: fetcher)
}
override func tearDown() {
viewModel = nil
fetcher = nil
tableView = nil
super.tearDown()
}
/// test the one cell can be selectable or not
func test_did_select_a_cell() {
let items = [Item(name: "", image: "",)]
// given
fetcher.items = items
viewModel.fetchItems()
let viewController = YourViewController()
let tableView = UITableView()
viewController.viewModel = viewModel
// when
viewController.tableView(tableView, didSelectRowAt: IndexPath(row: 0, section: 0))
let willBeSelected = viewController.tableView(tableView, willSelectRowAt: IndexPath(row: 0, section: 0))
// then
XCTAssertNotNil(willBeSelected)
XCTAssertTrue(viewModel.items.value[0].isSelected) // please note that items need to be binded - viewmodel-view
}
这篇关于TableView isSelected Scenario Swift 的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!