I am trying to unit test simple HttpClient behaviour. For that I have created an GenericHttpClientInterface protocol and concrete class GenericHttpClient that implements this protocol.
protocol GenericHttpClientInterface {
func makeRequest<T: Decodable>(request: URLRequest) -> Observable<T>
}
class GenericHttpClient: GenericHttpClientInterface {
func makeRequest<T: Decodable>(request: URLRequest) -> Observable<T> {
return URLSession.shared.rx.data(request: request).jsonDecode(to: T.self)
}
}
What I wanted to achieve is to mock that class :
class MockHttpClient: GenericHttpClientInterface {
var invokedMakeRequestCount = 0
var invokedMakeRequestParameters: (request: URLRequest, Void)?
var stubbedMakeRequestResult: Observable<Any>!
func makeRequest<T: Decodable>(request: URLRequest) -> Observable<T> {
invokedMakeRequestCount += 1
invokedMakeRequestParameters = (request, ())
return stubbedMakeRequestResult as! Observable<T>;
}
}
What gives ma a problem is that the method I am mocking has generic parameter T inside which is a class that the request will be decoded to. I don't know this parameter until I call this function so basically in MockHttpClient class for a property that stores stub data for makeRequest I've created:
stubbedMakeRequestResult: Observable<Any>
and after returning it I'm trying to cast that to result type Observable. This gives me an warning
Cast from 'Observable<Any>?' to unrelated type 'Observable<T>' always fails
and in consequence
Thread 1: signal SIGABRT.
Any idea how to stub that data?
Example test that creates SIGABRT:
class GenericHttpTest: XCTestCase {
var sut: Repository!
var mockHttpClient: MockHttpClient!
override func setUp() {
mockHttpClient = MockHttpClient()
sut = Repository(httpClient: mockHttpClient)
}
let test_mocked_data_stub = DataModelStruct(args: DataModelStruct.InsideModelStruct(foo1: "bar"))
func test_should_return_mocked_data_from_mock_http_client() {
mockHttpClient.stubbedMakeRequestResult = Observable.just(test_mocked_data_stub)
let response = try! sut.getFooBar().toBlocking().first()
XCTAssertEqual(response, test_mocked_data_stub)
}
}