I've got this simple class to store and instance of the type CurrentUser
to Realm
called CurrentUserStore
. There is one rule in this class, that is there can only be one record for an object at all times so for the register(user:)
func will need to clear the Realm for that type first before adding a new user. Here's the code:
final class CurrentUserStore: CurrentUserStoreProtocol {
private let realmAdapter: RealmAdapterInterface
init(realmAdapter: RealmAdapterInterface) {
self.realmAdapter = realmAdapter
}
func initiate() throws { ... }
func register(user: User) {
if !realmAdapter.retrieve(type: User.Type).isEmpty {
realmAdapter.clear(type: User.Type)
}
realmAdapter.add(user)
}
func retrieve() -> User { ... }
func unregister() { ... }
}
protocol RealmAdapterInterface {
func initiate() throws
func add<T: Any>(_ entry: T)
func retrieve<T: Any>(type: T.Type) -> [T]
func clear<T: Any>(type: T.Type)
}
Now, to test this behaviour, I have this:
class CurrentUserStoreTest: XCTestCase {
func testRegister_WhenAdapterRetrievesTooManyUsers_ShouldClearAdapterFirst() {
let realmAdapter = MockRealmAdapter(retrieveReturnValue: [User.random(), User.random()])
let store = CurrentUserStore(realmAdapter: realmAdapter)
let inputtedUser = User.random()
store.register(inputtedUser)
XCTAssertTrue(realmAdapter.isClearCalled)
XCTAssertTrue(realmAdapter.clearArgumentType is User.Type)
XCTAssertTrue(realmAdapter.isAddCalled)
XCTAssertEqual(inputtedUser, realmAdapter.addArgumentUser)
}
}
private final class MockRealmAdapter: RealmAdapterInterface {
private(set) var isInitiateCalled = false
private(set) var isAddCalled = false
private(set) var isRetrieveCalled = false
private(set) var isClearCalled = false
private(set) var initiateCallCount = 0
private(set) var addArgumentUser: Any?
private(set) var retrieveArgumentType: Any.Type?
private(set) var clearArgumentType: Any.Type?
private let retrieveOutputEntity: [Any]
init(retrieveReturnValue: [Any] = []) {
self.retrieveOutputEntity = retrieveOutputEntity
}
func initiate() throws {
isInitiateCalled = true
initiateCallCount += 1
}
func add<T>(_ entry: T) throws {
isAddCalled = true
addArgumentUser = entry
}
func retrieve<T>(type: T.Type) throws -> [T] {
isRetrieveCalled = true
retrieveArgumentType = type
}
func clear<T>(ype: T.Type) throws {
isClearCalled = true
clearArgumentType = type
}
}
Now, if I were to make the register(user:)
func into this:
func register(user: User) {
if !realmAdapter.retrieve(type: User.Type).isEmpty {
realmAdapter.add(user)
realmAdapter.clear(type: User.Type)
} else {
realmAdapter.add(user)
}
}
The test will still be green because we will still call add(_:)
and clear(type:)
funcs of the adapter class. Although because of the order of execution, the result will be very different. Any idea about how to test this order of execution?
Thanks.
Aucun commentaire:
Enregistrer un commentaire