定义你的数据模型
在本课程中,您将定义和测试的应⽤程序FoodTracker数据模型。⼀个数据模型表⽰在APP中的的信息结构。
学习⽬标
伤害的英文
在课程结束时,你将能够:
1.创建数据模型
2.写failable初始化⼀个⾃定义类
3.证明failable和nonfailable的不同,理解他们之间的差异和概念
4.通过编写和运⾏单元测试来测试数据模型
创建⼀个数据模型
现在你需要创建⼀个数据模型来存储菜谱场景所需要显⽰的信息。要做到这⼀点,我们需要定义个简单的类,⾥⾯有name,photo,rating
创建⼀个新的数据模型类
1.选择File > New > File (或按下Command+N)
2在对话框左边,选择iOS下的Source
3.选择Swift File,然后点击下⼀步
和前⾯创建RatingControl 所不同,对于数据模型,我们不需要继承其他类
4.在Save as旁,键⼊Meal
5.默认保存位置是项⽬⽬录,Group默认选择为你的App 名字FoodTracker,在Target选择,确保app和tests都被选中
6.点击Create。Xocde会创建⼀个名叫Meal.swift的⽂件
在Swift中,你能使⽤⼀个String表⽰⼀个name,使⽤UIImage表⽰photo,使⽤Int表⽰rating。因为⼀个菜谱总是会有⼀个name和rating。但不⼀定会有图⽚。所以UIImage是可选的
为菜谱定义数据模型
1.打开Meal.swift
2.修改导⼊语句为UIKit
import UIKit
默认1个Swift⽂件会导⼊为Foundation框架,它使你能够使⽤基础数据结构。你需要使⽤UIKit框架中的类,所以你需要导⼊UIKit,同时UIKit也能让你访问Foundation,因此你可以移除这个多余的Foundation语句
3.然后添加如下代码:
class Meal {
/
/ MARK: Properties
var name: String
var photo: UIImage?
亚加达外语专修学院
var rating: Int
}
代码定义了你需要存储的基础属性。你使⽤变量(var)⽽不是常量(let),因为他们在整个菜谱的⽣命周期中会发⽣改变
4.在属性代码下⽅,添加如下初始化代码:
// MARK: Initialization
init(name: String, photo: UIImage?, rating: Int) {
}
回忆⼀个初始化⽅法,当⼀个类的实例准备初始化时,我们可以为每个属性设置⼀个初始化值,或执⾏⼀些设置和初始化操作
5.通过参数值来给基础属性赋值
// Initialize stored properties.
lf.name = name
lf.photo = photo
lf.rating = rating
如果你尝试使⽤不正确的值来创建⼀个菜谱,会发⽣如⼀个空的name或负数的rating。你需要返回nil来表⽰item不能被创建,也不能设置为默认值。你需要添加代码来检查⼀些失败的情况
6.在初始化结束的地⽅,加⼊if语句来检查⽆效值
// Initialization should fail if there is no name or if the rating is negative.
if name.isEmpty || rating < 0 {
return nil
}
因为初始化函数中可能返回nil,所以你需要在初始化函数指出标识
7.点击fix-it,在init关键字后⾯来添加(?)
init?(name: String, photo: UIImage?, rating: Int) {
摩登家庭第四季电视剧这个初始化程序被称为failable initializer,它表⽰这个初始化程序可能会返回nil
现在整体init函数,应该如下所⽰:
// MARK: Initialization
init?(name: String, photo: UIImage?, rating: Int) {
// Initialize stored properties.
lf.name = name
lf.photo = photo
lf.rating = rating
// Initialization should fail if there is no name or if the rating is negative.
if name.isEmpty || rating < 0 {
return nil
}
}
测试你的数据
虽然你的数据模型编译了,但你还没有完全将其纳⼊到你的APP中。因此,很难判断是否已正确实现⼀切,在运⾏时你可能会遇到,没有考虑的边缘情况。
西安作品集培训
为了解决这种不确定性,你可以写单元测试,单元测试⽤于测试⼩的,独⽴的代码⽚段,以确保他们的⾏为正确。菜谱类正好是单元测试⼀个完美的候选⼈。Xcode已经帮你创建了⼀个单元测试⽂件
查看FoodTracker中的单元测试中的⽂件
1.打开FoodTrackerTests⽂件夹,通过点击三⾓形,展开⾥⾯的列表
2.打开 FoodTrackerTests.swift
花⼀点时间来了解⽂件中的代码
import UIKit
import XCTest
class FoodTrackerTests: XCTestCa {
override func tUp() {
super.tUp()
英语四级作弊
// Put tup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
}
func testExample() {
// This is an example of a functional test ca.
XCTAsrt(true, "Pass")
}
func testPerformanceExample() {
// This is an example of a performance test ca.
// Put the code you want to measure the time of here.
宁波化妆学校}
}
}
我们导⼊的XCText框架,是Xcode的测试框架。单元测试会定义在FoodTrackerTests类中,它继承⾃XCTestCa,代码注释解释
了tUp()和tearDown() ⽅法
你写的功能测试(⽤来检查⼀切产⽣的值是否符合你的预期)和性能测试(检查你代码的性能是不是符合你预期那样快)是主要的测试类型。因为你没有写任何耗性能的代码,所以这样你只要写功能测
试即可。
⼀般在我们的测试⽅法前,会加上text前缀,如我们先要测试init⽅法,会这么写testMealInitialization
为菜谱对象的初始化函数编写单元测试
1.在 FoodTrackerTests.swift中,删除测试模版
import UIKit
import XCTest
class FoodTrackerTests: XCTestCa {
}
本例中,我们不使⽤任何模版代码
2.在类中,添加如下⽅法
// Tests to confirm that the Meal initializer returns when no name or a negative rating is provided.
func testMealInitialization() {
}
添加注释是⼀个好习惯,可以帮助你或其他浏览你代码的⼈,看懂你这个⽅法的意思,是要做什么
3.⾸先添加⼀个通过的测试⽤例。添加注释
// Success ca.
let potentialItem = Meal(name: "Newest meal", photo: nil, rating: 5)
XCTAsrtNotNil(potentialItem)
XCTAsrtNotNil是测试Meal对象在初始化后不为nil,这意味这你提供的参数会在初始化程序中成功创建⼀个Meal对象。
4.现在添加⼀个Meal失败的测试⽤例。添加如下代码:
// Failure cas.一眨眼
let noName = Meal(name: "", photo: nil, rating: 0)
XCTAsrtNil(noName, "Empty name is invalid")
XCTAsrtNil断⾔这个对象是nil。本例中,意思是noName这个对象为nil,意味着它初始化失败。你期望这个初始化失败,因为这个名字是⼀个空字符串,你明确地针对初始程序测试。
视听英语5.我们在添加⼀个测试失败的⽤例,但这次我们断⾔他会成功:
let badRating = Meal(name: "Really bad rating", photo: nil, rating: -1)
XCTAsrtNotNil(badRating)
你期望这个⽤例会失败,因为rating为负数
您可以通过按下Command-U在运⾏单元测试。最后⼀个测试⽤例预期失败,因为你断⾔对象⾮nil,它实际上是nil。
运⾏单元测试
1.在FoodTrackerTests.swift中,找到testMealInitialization()单元测试
2.在测试名称的左边,找到⼀个菱形
3.将⿏标悬停在菱形上会出现⼀个⼩的运⾏按钮
4.点击这个执⾏按钮来运⾏单元测试
检查站:你的应⽤程序运⾏在你刚刚编写的单元测试上。前两个测试⽤例应该通过,最后应该失败。
正如你所看到的,单元测试有助于捕获代码中的错误。如果你真的希望在最后⼀个测试中的对象是⾮nil,你会在测试过程中发现这个错误。(在这种情况下,是因为你故意写了⼀个失败的测试案例,你可以回头去解决你的测试案例)
修复测试⽤例
1.在FoodTrackerTests.swift中找到testMealInitialization()
2.修改代码为
XCTAsrtNil(badRating, "Negative ratings are invalid, be positive")
完整的⽅法看起来应该是这样:
// Tests to confirm that the Meal initializer returns when no name or a negative rating is provided. func testMealInitialization() {
// Success ca.
let potentialItem = Meal(name: "Newest meal", photo: nil, rating: 5)
XCTAsrtNotNil(potentialItem)
// Failure cas.
let noName = Meal(name: "", photo: nil, rating: 0)
中文在线翻译成英文XCTAsrtNil(noName, "Empty name is invalid")
let badRating = Meal(name: "Really bad rating", photo: nil, rating: -1)
XCTAsrtNil(badRating, "Negative ratings are invalid, be positive")
}
检查站:运⾏你刚刚编写单元测试。所有的测试⽤例应该会通过。