Skip to content

Commit 00d09b9

Browse files
committed
Add Testing Codable blogpost
1 parent ac13e64 commit 00d09b9

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
---
2+
layout: post
3+
author: matt
4+
title: "Testing Codable"
5+
date: 2019-05-10 19:55:56 +0200
6+
comments: true
7+
categories:
8+
---
9+
10+
Codable is a great protocol available in Swift. It makes it possible to create a type safe JSON representations of structures used within our application with zero boilerplate.
11+
12+
```swift
13+
struct Person: Codable {
14+
let name: String
15+
let email: String
16+
let age: Int
17+
}
18+
```
19+
20+
Once the structure conforms to `Codable` everything works out of the box. There's a nice way to test those structures and make sure that everything gets the exact JSON format that we aligned with backend.
21+
<!--more-->
22+
23+
Let's create the following protocol in the test bundle:
24+
```swift
25+
protocol JSONTestable {
26+
init?(_ json: String)
27+
func json() -> String?
28+
}
29+
```
30+
31+
After that we can immediately provide an extension which conforms to that protocol in the test bundle:
32+
```swift
33+
extension JSONTestable where Self: Codable {
34+
init?(_ json: String) {
35+
guard
36+
let data = json.data(using: .utf8),
37+
let decoded = try? JSONDecoder().decode(Self.self, from: data)
38+
else { return nil }
39+
self = decoded
40+
}
41+
42+
func json() -> String? {
43+
guard let data = try? JSONEncoder().encode(self) else { return nil }
44+
return String(data: data, encoding: .utf8)
45+
}
46+
}
47+
```
48+
49+
Then there's only one simple step which needs to be done in the test bundle in order to test the structure:
50+
`PersonTests.swift`:
51+
```swift
52+
extension Person: JSONTestable {}
53+
```
54+
55+
That's it! Now we can easily test the result of the serialization and deserialization :)
56+
57+
Example tests:
58+
```swift
59+
final class PersonTests: XCTestCase {
60+
func testJsonSerialization() {
61+
let person = Person(name: "John Appleased", email: "john@appleased.com", age: 30)
62+
XCTAssertEqual(personJson, person.json()) //
63+
}
64+
65+
func testJsonDeserialization() {
66+
let person = Person(name: "John Appleased", email: "john@appleased.com", age: 30)
67+
XCTAssertEqual(person, Person(personJson)) //
68+
}
69+
}
70+
71+
private let personJson = """
72+
{"name":"John Appleased","email":"john@appleased.com","age":30}
73+
"""
74+
75+
extension Person: JSONTestable, Equatable {}
76+
```
77+
78+
What do you think about this method? Is there anything which could be improved in this implementation? Please let us know :)

0 commit comments

Comments
 (0)