UndoManager 的 undo 方法在测试时执行 registerUndo 的次数
Posted
技术标签:
【中文标题】UndoManager 的 undo 方法在测试时执行 registerUndo 的次数【英文标题】:undo method of UndoManager execute number of times the registerUndo while testing 【发布时间】:2021-01-04 13:32:37 【问题描述】:我只从 TestClass 调用了一次 undoMethod。但是undo方法执行了registerUndo的次数。
这是我的测试课。
import XCTest
@testable import UnitTestProject
class UnitTestProjectTests: XCTestCase
func testUndo()
let model = TestModel()
model.increment()
XCTAssertEqual(model.count, 1)
model.increment()
XCTAssertEqual(model.count, 2)
model.increment()
XCTAssertEqual(model.count, 3)
model.undo()
XCTAssertEqual(model.count, 2)
这是目标类。
import Foundation
class TestModel
let undoManager = UndoManager()
var count = 0
func registerUndo()
if (undoManager.isUndoRegistrationEnabled)
undoManager.registerUndo(withTarget: self, handler: _ in
print("undo is executed")
self.count -= 1
)
func increment()
count += 1
registerUndo()
func undo()
if(undoManager.canUndo)
undoManager.undo()
如你所见,这个测试代码只调用了一次undo方法。但是undo方法实际上调用了3次,所以这个测试会失败。
this is console log
Test Case '-[UnitTestProjectTests.UnitTestProjectTests testUndo]' started.
undo is executed
undo is executed
undo is executed
/Users/project/UnitTestProject/UnitTestProjectTests/UnitTestProjectTests.swift:27: error: -[UnitTestProjectTests.UnitTestProjectTests testUndo] : XCTAssertEqual failed: ("0") is not equal to ("2")
Test Case '-[UnitTestProjectTests.UnitTestProjectTests testUndo]' failed (0.019 seconds).
Test Suite 'UnitTestProjectTests' failed at 2021-01-04 22:21:43.585.
Executed 1 test, with 1 failure (0 unexpected) in 0.019 (0.020) seconds
Test Suite 'UnitTestProjectTests.xctest' failed at 2021-01-04 22:21:43.585.
Executed 1 test, with 1 failure (0 unexpected) in 0.019 (0.021) seconds
Test Suite 'Selected tests' failed at 2021-01-04 22:21:43.586.
Executed 1 test, with 1 failure (0 unexpected) in 0.019 (0.023) seconds
我想问以下2点。
·为什么这个undo方法在测试时执行了registerUndo的次数?
・如何测试这样的Undo和Redo方法?
最后,感谢您对这个问题的思考,这是用糟糕的英语写成的。
【问题讨论】:
【参考方案1】:默认情况下,undoManager 将在同一个 runloop 循环中执行的所有操作分组。在您的示例中,您执行三个连续的操作,因此这三个操作在 undoManager 堆栈中构成一个组。在撤消时,这三个操作一次被还原,这就是为什么您会看到处理程序块被调用了 3 次而不是 1 次。
您可以更改默认行为,但要以自己管理分组为代价,因为任何操作,即使是单个操作,都必须包含在一个组中。我给你举个例子,但请注意我是一个 Objective-c 用户并且没有 swift 的实践(幸运的是这里的语法很简单)。
首先,您应该停用自动分组操作的默认行为:
undoManager.setGroupByEvent = NO
然后每个对 registerUndo 的调用都应该被对 beginUndoGrouping 和 endUndoGrouping 的调用包围(可以使用专用函数来简化):
undoManager.beginUndoGrouping
undoManager.registerUndo(withTarget: self, handler: _ in
print("undo is executed")
self.count -= 1
)
undoManager.endUndoGrouping
现在,您必须调用 undo 三次才能获得与示例相同的结果,并且您应该能够更简单地分解测试。
【讨论】:
谢谢你,我得到了帮助!!我的测试成功了!以上是关于UndoManager 的 undo 方法在测试时执行 registerUndo 的次数的主要内容,如果未能解决你的问题,请参考以下文章