I have a protocol which has quite more methods, it looks like:
protocol MessageService {
//configuration
var fetchOfflineMessagesOnLogin: Bool {get set}//default true
var maxCharsInMessage: UInt {get set}//default 400
//connection
var connectionState: ConnectionState { get }
func login(hostName: String, port: UInt, username: String, password: String)
func logoutFromService()
//contacts
func sendContactRequest(to peerUId: String)
func acceptContactRequest(from peerUId: String)
func removeContact(peerUId: String)
}
I am unit testing the controller class which takes this protocol and operates on it according to various states.
There are some functions in this controller class that only interacts with only one method out of many protocol methods, and I while testing those methods, I wrote following unit test:
func testSendContactRequest() {
class MessageServiceMock: MessageService {
func sendContactRequest(to peerUId: String) {
//tests
}
}
//unit test setup
let controller = Controller(service: MessageServiceMock())
//...
}
func testAcceptContactRequest() {
class MessageServiceMock: MessageService {
func acceptContactRequest(from peerUId: String) {
//tests
}
}
//unit test setup
let controller = Controller(service: MessageServiceMock())
//...
}
But, apparently, compiler throws error
MessageServiceMock does not conform to protocol
So I tried to make all the protocol methods optional by adding extension to it as (in test class file only):
fileprivate extension MessageService {
var fetchOfflineMessagesOnLogin: Bool {
get { return true }
set {}
}
var maxCharsInMessage: UInt {
get { return 400 }
set {}
}
var connectionState: ConnectionState {
return .connecting
}
func login(hostName: String, port: UInt, username: String, password: String) {}
func logoutFromService() {}
func sendContactRequest(to peerUId: String) {}
func acceptContactRequest(from peerUId: String) {}
func removeContact(peerUId: String) {}
}
Now error is gone and everything works fine.
I know other way to make protocol methods optional is using @objc
optional
keywords, but I can't use those as MessageService
contains some Swift value types those are not convertible to ObjC objects.
So, is this solution is acceptable?
Are there any things that I can improve?