When writing tests, I often have to create "mocks" of classes within my app. Mocking is a really common technique used in the Ruby and JavaScript communities but isn't used much in Swift or Objective-C. The most popular mocking library is open source: http://ocmock.org
So here's what I want from Xcode, out of the box: I want to be able to create mocks of a test subject's dependencies and use dependency injection to give them to the subject. Then I can run the code on the subject and assert that the mock received certain messages. It's cumbersome to describe a hypothetical syntax, so let me provide you with a few tests from a Ruby codebase I maintain.
it "handles swiftlint not being installed" do
allow_any_instance_of(Swiftlint).to receive(:is_installed?).and_return(false)
expect { @swiftlint.lint_files }.to raise_error("swiftlint is not installed")
end
it 'default config is nil, unspecified' do
allow(@swiftlint.git).to receive(:added_files).and_return([])
allow(@swiftlint.git).to receive(:modified_files).and_return([
'spec/fixtures/SwiftFile.swift',
])
Equivalent tests written in vanilla XCTest are cumbersome, involve extensive subclassing and a tonne of boilerplate. The sad truth is: most developers don't write enough unit tests, and the lack of a decent, first-party mocking library would go a long way to improve this problem.
The static nature of Swift, and to some extent of Objective-C, make creating mocks a challenge. But I know you're up to it.
Description
When writing tests, I often have to create "mocks" of classes within my app. Mocking is a really common technique used in the Ruby and JavaScript communities but isn't used much in Swift or Objective-C. The most popular mocking library is open source: http://ocmock.org
So here's what I want from Xcode, out of the box: I want to be able to create mocks of a test subject's dependencies and use dependency injection to give them to the subject. Then I can run the code on the subject and assert that the mock received certain messages. It's cumbersome to describe a hypothetical syntax, so let me provide you with a few tests from a Ruby codebase I maintain.
it "handles swiftlint not being installed" do allow_any_instance_of(Swiftlint).to receive(:is_installed?).and_return(false) expect { @swiftlint.lint_files }.to raise_error("swiftlint is not installed") end
it 'default config is nil, unspecified' do allow(@swiftlint.git).to receive(:added_files).and_return([]) allow(@swiftlint.git).to receive(:modified_files).and_return([ 'spec/fixtures/SwiftFile.swift', ])
expect_any_instance_of(Swiftlint).to receive(:lint) .with(hash_including(:config => nil), '') .once .and_return(@swiftlint_response)
@swiftlint.lint_files end
Equivalent tests written in vanilla XCTest are cumbersome, involve extensive subclassing and a tonne of boilerplate. The sad truth is: most developers don't write enough unit tests, and the lack of a decent, first-party mocking library would go a long way to improve this problem.
The static nature of Swift, and to some extent of Objective-C, make creating mocks a challenge. But I know you're up to it.
- Product Version: Created: 2017-10-08T16:03:49.657550 Originated: 2017-08-10T00:00:00 Open Radar Link: http://www.openradar.me/34875844