TestingMidOpen-ended

How do you test a ViewModel?

Explanation & Code

Answer: Inject mock dependencies, call ViewModel methods, and assert on @Published properties. Use async/await for async ViewModels.

Code Example:

@MainActor
class ArticleViewModelTests: XCTestCase {

    func test_load_populatesArticles() async throws {
        // Arrange
        let mockRepo = MockArticleRepository()
        mockRepo.stubbedArticles = [Article(id: "1", title: "Test")]
        let viewModel = ArticleViewModel(repository: mockRepo)

        // Act
        await viewModel.load()

        // Assert
        XCTAssertFalse(viewModel.articles.isEmpty)
        XCTAssertEqual(viewModel.articles.first?.title, "Test")
        XCTAssertFalse(viewModel.isLoading)
    }

    func test_load_setsErrorOnFailure() async {
        let mockRepo = MockArticleRepository()
        mockRepo.shouldFail = true
        let viewModel = ArticleViewModel(repository: mockRepo)

        await viewModel.load()

        XCTAssertNotNil(viewModel.errorMessage)
    }
}

Rate your understanding:

Ready to practice more Testing?

Test yourself with our interactive quiz mode or browse all curated questions for this topic.