mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-09 22:36:01 +05:45
Prototype of a module with Firestore fakes for testing dependent code in Swift (#7668)
* Firestore testing support prototype * SwiftPM target * Comments and formatting * Move FirebaseFirestoreTestingSupport.podspec to subfolder * Swift PM updated * Headers location and imports * Podspec version update * Brief readme * Swift PM FirestoreTestingSupportTests target added * Formatting * Move FirebaseFirestoreTestingSupport.podspec back to root * README updates * Cleanup podspec * README
This commit is contained in:
1 parent
5063d9fba5
commit
c9c03467ff
8 files changed
+403
No files matched your search
@@ -734,6 +734,104 @@
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FirebaseAuthCombineSwift-Beta"
|
||||
BuildableName = "FirebaseAuthCombineSwift-Beta"
|
||||
BlueprintName = "FirebaseAuthCombineSwift-Beta"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FirebaseCombineSwift-Beta"
|
||||
BuildableName = "FirebaseCombineSwift-Beta"
|
||||
BlueprintName = "FirebaseCombineSwift-Beta"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FirebaseFunctionsCombineSwift-Beta"
|
||||
BuildableName = "FirebaseFunctionsCombineSwift-Beta"
|
||||
BlueprintName = "FirebaseFunctionsCombineSwift-Beta"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FirebaseAuthCombineSwift"
|
||||
BuildableName = "FirebaseAuthCombineSwift"
|
||||
BlueprintName = "FirebaseAuthCombineSwift"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FirebaseCombineSwift"
|
||||
BuildableName = "FirebaseCombineSwift"
|
||||
BlueprintName = "FirebaseCombineSwift"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FirebaseFirestoreTestingSupport"
|
||||
BuildableName = "FirebaseFirestoreTestingSupport"
|
||||
BlueprintName = "FirebaseFirestoreTestingSupport"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FirebaseFunctionsCombineSwift"
|
||||
BuildableName = "FirebaseFunctionsCombineSwift"
|
||||
BlueprintName = "FirebaseFunctionsCombineSwift"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
@@ -922,6 +1020,16 @@
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FirestoreTestingSupportTests"
|
||||
BuildableName = "FirestoreTestingSupportTests"
|
||||
BlueprintName = "FirestoreTestingSupportTests"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1240"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
<TestableReference
|
||||
skipped = "NO">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "FirestoreTestingSupportTests"
|
||||
BuildableName = "FirestoreTestingSupportTests"
|
||||
BlueprintName = "FirestoreTestingSupportTests"
|
||||
ReferencedContainer = "container:">
|
||||
</BuildableReference>
|
||||
</TestableReference>
|
||||
</Testables>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -0,0 +1,58 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'FirebaseFirestoreTestingSupport'
|
||||
s.version = '1.0.0'
|
||||
s.summary = 'Firebase SDKs testing support types and utilities.'
|
||||
|
||||
s.description = <<-DESC
|
||||
Type declarations and utilities needed for unit testing of the code dependent on Firebase SDKs
|
||||
DESC
|
||||
|
||||
s.homepage = 'https://developers.google.com/'
|
||||
s.license = { :type => 'Apache', :file => 'LICENSE' }
|
||||
s.authors = 'Google, Inc.'
|
||||
|
||||
s.source = {
|
||||
:git => 'https://github.com/Firebase/firebase-ios-sdk.git',
|
||||
:tag => 'CocoaPods-' + s.version.to_s
|
||||
}
|
||||
|
||||
ios_deployment_target = '10.0'
|
||||
osx_deployment_target = '10.12'
|
||||
tvos_deployment_target = '10.0'
|
||||
watchos_deployment_target = '6.0'
|
||||
|
||||
s.ios.deployment_target = ios_deployment_target
|
||||
s.osx.deployment_target = osx_deployment_target
|
||||
s.tvos.deployment_target = tvos_deployment_target
|
||||
s.watchos.deployment_target = watchos_deployment_target
|
||||
|
||||
s.cocoapods_version = '>= 1.4.0'
|
||||
s.prefix_header_file = false
|
||||
s.requires_arc = true
|
||||
|
||||
base_dir = 'FirebaseTestingSupport/Firestore/'
|
||||
|
||||
s.source_files = [
|
||||
base_dir + 'Sources/**/*.{m,mm,h}',
|
||||
'Firestore/Source/API/*\+Internal.h'
|
||||
]
|
||||
|
||||
s.public_header_files = base_dir + '**/*.h'
|
||||
|
||||
s.dependency 'FirebaseFirestore', '~> 7.7'
|
||||
|
||||
s.pod_target_xcconfig = {
|
||||
'GCC_C_LANGUAGE_STANDARD' => 'c99',
|
||||
'OTHER_CFLAGS' => '-fno-autolink',
|
||||
'HEADER_SEARCH_PATHS' =>
|
||||
'"${PODS_TARGET_SRCROOT}" '
|
||||
}
|
||||
|
||||
s.test_spec 'unit' do |unit_tests|
|
||||
unit_tests.scheme = { :code_coverage => true }
|
||||
unit_tests.platforms = {:ios => ios_deployment_target, :osx => osx_deployment_target, :tvos => tvos_deployment_target}
|
||||
unit_tests.source_files = [
|
||||
base_dir + 'Tests/**/*.swift'
|
||||
]
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#import "FirebaseTestingSupport/Firestore/Sources/Public/FirebaseFirestoreTestingSupport/FIRQueryFake.h"
|
||||
|
||||
#import "Firestore/Source/API/FIRQuery+Internal.h"
|
||||
|
||||
@implementation FIRQueryFake
|
||||
|
||||
- (instancetype)init {
|
||||
// The object is partially initialized. Make sure the methods used during testing are overridden.
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)getDocumentsWithCompletion:(FIRQuerySnapshotBlock)completion {
|
||||
if (self.getDocumentsHandler) {
|
||||
self.getDocumentsHandler(completion);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#import <FirebaseFirestore/FIRQuery.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef void (^FIRFirestoreGetDocumentsHandler)(FIRQuerySnapshotBlock completion);
|
||||
|
||||
/// A fake object to replace a real `Query` in tests.
|
||||
NS_SWIFT_NAME(QueryFake)
|
||||
@interface FIRQueryFake : FIRQuery
|
||||
|
||||
- (instancetype)init;
|
||||
|
||||
/// The block to be called each time when `getDocuments(completion:)` method is called.
|
||||
@property(nonatomic, nullable, copy) FIRFirestoreGetDocumentsHandler getDocumentsHandler;
|
||||
|
||||
// TODO: Implement other handlers as needed.
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright 2021 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import XCTest
|
||||
@testable import FirebaseFirestoreTestingSupport
|
||||
|
||||
class QueryFakeTests: XCTestCase {
|
||||
func testQueryFakeConstructor() throws {
|
||||
let fakeQuery = QueryFake()
|
||||
XCTAssertNotNil(fakeQuery)
|
||||
XCTAssertTrue(fakeQuery.isKind(of: Query.self))
|
||||
}
|
||||
|
||||
func testQueryFakeGetDocumentsHandler() {
|
||||
let fakeQuery = QueryFake()
|
||||
|
||||
let handlerExpectation = expectation(description: "Handler called")
|
||||
fakeQuery.getDocumentsHandler = { completion in
|
||||
handlerExpectation.fulfill()
|
||||
|
||||
completion(nil, nil)
|
||||
}
|
||||
|
||||
let completionExpectation = expectation(description: "Completion called")
|
||||
fakeQuery.getDocuments { snapshot, error in
|
||||
completionExpectation.fulfill()
|
||||
XCTAssertNil(snapshot)
|
||||
XCTAssertNil(error)
|
||||
}
|
||||
|
||||
wait(for: [handlerExpectation, completionExpectation], timeout: 0.5)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
# Firebase Testing Support (for automated test developers)
|
||||
|
||||
Firebase Testing Support is a collection of libraries that provide type definitions and tools required for writing tests for code that uses Firebase, e.g.:
|
||||
|
||||
- Instances of types like `Query` cannot be created with a simple constructor which makes unit testing of the code that depends on them difficult/impossible. Firestore Testing Support lib provides a type `QueryFake` that can be instantiated and used instead of actual `Query` instances in the tests.
|
||||
|
||||
## Usage
|
||||
|
||||
### Add dependency to your test target
|
||||
|
||||
#### Cocoapods
|
||||
|
||||
```
|
||||
tests.dependency 'FirebaseFirestoreTestingSupport', '~> 1.0'
|
||||
```
|
||||
|
||||
#### Swift Package Manager
|
||||
|
||||
```
|
||||
dependencies: [
|
||||
...
|
||||
"FirebaseFirestoreTestingSupport"
|
||||
],
|
||||
|
||||
```
|
||||
|
||||
### Use the fake types in the tests instead of real types
|
||||
|
||||
See test for example, e.g. [QueryFakeTests.swift](../FirebaseTestingSupport/Firestore/Tests/QueryFakeTests.swift).
|
||||
|
||||
## Development
|
||||
|
||||
### Generate project
|
||||
|
||||
#### Cocoapods
|
||||
|
||||
E.g. for `FirebaseFirestoreTestingSupport` run the following command for the root repo directory:
|
||||
|
||||
```
|
||||
pod gen --auto-open --local-sources=./ FirebaseFirestoreTestingSupport.podspec --platforms=ios
|
||||
```
|
||||
|
||||
#### Swift Package Manager
|
||||
|
||||
- Open the main package definition:
|
||||
|
||||
```
|
||||
xed Package.swift
|
||||
```
|
||||
|
||||
- Select (or add if not exists yet) a scheme for the test target, e.g. `FirestoreTestingSupportTests`
|
||||
|
||||
- make required modifications and run tests as needed.
|
||||
@@ -837,6 +837,28 @@ let package = Package(
|
||||
.define("FIR_VERSION", to: firebaseVersion),
|
||||
]
|
||||
),
|
||||
|
||||
// MARK: Testing support
|
||||
|
||||
.target(
|
||||
name: "FirebaseFirestoreTestingSupport",
|
||||
dependencies: ["FirebaseFirestore"],
|
||||
path: "FirebaseTestingSupport/Firestore/Sources",
|
||||
publicHeadersPath: "./",
|
||||
cSettings: [
|
||||
.headerSearchPath("../../.."),
|
||||
.headerSearchPath("../../../Firestore/Source/Public/FirebaseFirestore"),
|
||||
]
|
||||
),
|
||||
.testTarget(
|
||||
name: "FirestoreTestingSupportTests",
|
||||
dependencies: ["FirebaseFirestoreTestingSupport"],
|
||||
path: "FirebaseTestingSupport/Firestore/Tests",
|
||||
cSettings: [
|
||||
.headerSearchPath("../../.."),
|
||||
]
|
||||
),
|
||||
|
||||
],
|
||||
cLanguageStandard: .c99,
|
||||
cxxLanguageStandard: CXXLanguageStandard.gnucxx14
|
||||
|
||||
Reference in new issue
Block a user