https://github.com/filimo/testableapp
The demo project to show how to organize code to make SwiftUI apps easy to be test.
https://github.com/filimo/testableapp
swift swiftui testautomation
Last synced: 2 months ago
JSON representation
The demo project to show how to organize code to make SwiftUI apps easy to be test.
- Host: GitHub
- URL: https://github.com/filimo/testableapp
- Owner: filimo
- Created: 2021-12-24T18:32:01.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2021-12-24T18:48:53.000Z (over 4 years ago)
- Last Synced: 2025-06-15T01:36:54.054Z (about 1 year ago)
- Topics: swift, swiftui, testautomation
- Language: Swift
- Homepage:
- Size: 3.68 MB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# TestableApp
I combined [the idea to use functional programming](https://www.swiftbysundell.com/articles/dependency-injection-and-unit-testing-using-async-await/#adding-a-bit-of-functional-programming) instead of an loader instance in ModelView(I prefer to think of it as a service) and [Resolver](https://github.com/hmlongco/Resolver.git).

## Functional signatures for loads or actions
```swift
typealias AsyncAction = (T) async throws -> Void
typealias Loading = () async throws -> T
```
## How to use it in the app
```swift
@main
struct TestableApp: App {
init() {
Resolver.register {
NewsService.initLoader()
}
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
```
## How to use it in a view for running
```swift
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Resolver.register {
NewsService.mockLoader() //the app isn't running in canvas preview
// NewsService.initLoader() //the app is running in canvas preview
}
return ContentView()
}
}
```
## How to use it in tests
```swift
class TestableAppTests: XCTestCase {
private var service: NewsService!
override func setUpWithError() throws {
// Put setup code here. This method is called before the invocation of each test method in the class.
Resolver.register {
NewsService.mockLoader()
}
service = NewsService()
}
func testLoadingNews() async throws {
XCTAssertEqual(service.news.count, 0)
try await service.fetchAllNews()
XCTAssertGreaterThan(service.news.count, 0)
}
}
```