编写测试用例时弱变量变为空?
Posted
技术标签:
【中文标题】编写测试用例时弱变量变为空?【英文标题】:weak variable is becoming nil while writing testcase? 【发布时间】:2019-11-26 09:59:53 【问题描述】:您好,我正在为ViewModel
中的一个函数编写一个测试用例,其中我使用的是弱变量,
在测试函数时,弱变量变为 nil ,我也在调用测试函数之前实例化了它并为该对象提供了值。为什么它变成了 nil ,那我该如何测试呢!!!
我也不能将弱变量设为强类型!!,正在处理其他代码
编译器警告 - 实例将立即被释放,因为属性“源”是“弱”
代码
func testFundTrip()
viewModel.source = SourceViewTypeMock()
viewModel.fundTrip(trip)
在 ViewModel 中
func fundTrip(_ trip: TravelTrip)
if let source = source
// Here source is becoming nil ?? why
测试用例方法是否有变量范围的东西?
【问题讨论】:
只是一个可能有帮助的评论,我认为您可能对它的架构有疑问。如果SourceViewTypeMock
是 UIView
的子类,则不应将其传递给 ViewModel。拥有 ViewModel 的目的是将业务逻辑与 UI 代码分开。您不应该将 UIKit 导入 ViewModel。虚拟机应该触发网络代码、获取响应、格式化、将格式存储在某处并通过委托/协议或回调等通知视图。
@simon 事情是 sourceviewtypemock 是符合某些 sourcevietype 协议的类,根本不使用或导入 uikit
【参考方案1】:
警告准确地告诉您正在发生的事情。您只有一个指向值的弱指针,因此在赋值语句之后没有任何东西可以让您的 SourceViewTypeMock
保持活力。解决方案是创建一个强引用。你需要一个不允许编译器优化的,所以它必须在这个函数之外。所以你让它成为测试用例的一个属性。
如果它是不可变的,你可以这样做:
class TheTestCase: XCTestCase
let sourceMock = SourceViewTypeMock()
func testFundTrip()
viewModel.source = sourceMock
viewModel.fundTrip(trip)
如果它是可变的,那么您可能需要确保在 setUp
中重新创建它:
class TheTestCase: XCTestCase
var sourceMock: SourceViewTypeMock!
override func setUp()
sourceMock = SourceViewTypeMock()
func testFundTrip()
viewModel.source = sourceMock
viewModel.fundTrip(trip)
【讨论】:
虽然我已经通过将本地变量分配给 sourceviewmock 来做到这一点。感谢您的洞察力! 局部变量在最后一次使用后不能保证继续存在,因此强引用可能会在调用fundTrip()
之前消失。这取决于优化器。
局部变量将一直存在,直到函数在活动堆栈中或在内存中,并且该变量将具有弱变量的引用,因此弧计数将始终为 1,直到函数处于活动状态。所以不会有问题!
因为 ARC 可以在最后一次访问局部变量后的任何时候插入释放。因此,如果您有类似let x = SomeObject(); print(x)
的代码,并且在该函数中不再访问x
,那么ARC 可以在print
完成后释放x
。它不必等到x
有效的范围结束。 let x = SomeObject; self.weakRef = x
是一样的。 x
是唯一的强引用,ARC 可以在最后一次使用后立即免费发布 x
。由于weakRef
不会创建强引用,因此x
可以在此时被销毁,并将weakRef
设置为nil。
ARC 没有有插入该版本;它完全是优化器的属性。因此,在未优化的代码中,您可能会看到一种行为,但是当您打开优化器时,您可能会看到另一种行为。以上是关于编写测试用例时弱变量变为空?的主要内容,如果未能解决你的问题,请参考以下文章
在使用 Jasmine Karma 编写测试用例时,我无法涵盖正在执行的处理程序
当我尝试运行测试用例时,它显示了 shallowMount 错误,如何修复 VUE.JS 中的 ShallowMount 错误?