【发布时间】:2020-08-28 11:52:15
【问题描述】:
我正在尝试对简单的 HttpClient 行为进行单元测试。为此,我创建了一个 GenericHttpClientInterface 协议和实现该协议的具体类 GenericHttpClient。
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)
}
}
我想要实现的是模拟该类:
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>;
}
}
给 ma 带来问题的是,我正在模拟的方法具有通用参数 T,其中是一个请求将被解码到的类。我不知道这个参数,直到我调用这个函数,所以基本上在 MockHttpClient 类中为一个存储我创建的 makeRequest 存根数据的属性:
stubbedMakeRequestResult: Observable<Any>
返回它后,我试图将其转换为结果类型 Observable。这给了我一个警告
Cast from 'Observable<Any>?' to unrelated type 'Observable<T>' always fails
结果
Thread 1: signal SIGABRT.
知道如何存根这些数据吗?
创建 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)
}
}
【问题讨论】:
-
您似乎理解了这个错误 - 您的存根类型与
makeRequest的返回类型不同。因此,您要么需要在makeRequest中创建存根数据并检查类型。或者你可能会为你正在使用的类型重载makeRequest
标签: ios swift unit-testing mocking xctest