How to mock URL struct?How do I test a private function or a class that has private methods, fields or inner classes?How to change the name of an iOS app?What's the difference between faking, mocking, and stubbing?How can I make a UITextField move up when the keyboard is present - on starting to edit?How to make mock to void methods with MockitoWhat is Mocking?How to call Objective-C code from SwiftURLSession instance method `downloadTask` erroriOS - Mocking UserDefault before loading the view controllerWhat should I include in my network mocking function?
Is there an official reason for not adding a post-credits scene?
In Stroustrup's example, what does this colon mean in `return 1 : 2`? It's not a label or ternary operator
Multiple SQL versions with Docker
What if the end-user didn't have the required library?
29er Road Tire?
List of newcommands used
How to safely wipe a USB flash drive
IP addresses from public IP block in my LAN
Nominativ or Akkusativ
Should homeowners insurance cover the cost of the home?
How to use dependency injection and avoid temporal coupling?
Shutter speed -vs- effective image stabilisation
Homotopy limit over a diagram of nullhomotopic maps
Should I decline this job offer that requires relocating to an area with high cost of living?
Why does this derived table improve performance?
Are there any of the Children of the Forest left, or are they extinct?
Causes of bimodal distributions when bootstrapping a meta-analysis model
Emotional immaturity of comic-book version of superhero Shazam
PWM 1Hz on solid state relay
What are the differences between credential stuffing and password spraying?
Target/total memory is higher than max_server_memory
How to make a chinese doggy bag?
How can I get people to remember my character's gender?
How should I tell my manager I'm not paying for an optional after work event I'm not going to?
How to mock URL struct?
How do I test a private function or a class that has private methods, fields or inner classes?How to change the name of an iOS app?What's the difference between faking, mocking, and stubbing?How can I make a UITextField move up when the keyboard is present - on starting to edit?How to make mock to void methods with MockitoWhat is Mocking?How to call Objective-C code from SwiftURLSession instance method `downloadTask` erroriOS - Mocking UserDefault before loading the view controllerWhat should I include in my network mocking function?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I am writing some code to be able to make testing easier. After researching, I found a good way of making URLSession testable is to make it conform to a protocol and use that protocol in the class I need to test. I applied the same method to URL. However, I now need to downcast the url parameter as a URL type. This seems a bit "dangerous" to me. What is the proper way to make URL testable? How can I also mock the URLSessionDataTask type returned by dataTask?
import Foundation
protocol URLSessionForApiRequest
func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
protocol URLForApiRequest
init?(string: String)
extension URLSession: URLSessionForApiRequest
extension URL: URLForApiRequest
class ApiRequest
class func makeRequest(url: URLForApiRequest, urlSession: URLSessionForApiRequest)
guard let url = url as? URL else return
let task = urlSession.dataTask(with: url) _, _, _ in print("DONE")
task.resume()
ios swift unit-testing
add a comment |
I am writing some code to be able to make testing easier. After researching, I found a good way of making URLSession testable is to make it conform to a protocol and use that protocol in the class I need to test. I applied the same method to URL. However, I now need to downcast the url parameter as a URL type. This seems a bit "dangerous" to me. What is the proper way to make URL testable? How can I also mock the URLSessionDataTask type returned by dataTask?
import Foundation
protocol URLSessionForApiRequest
func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
protocol URLForApiRequest
init?(string: String)
extension URLSession: URLSessionForApiRequest
extension URL: URLForApiRequest
class ApiRequest
class func makeRequest(url: URLForApiRequest, urlSession: URLSessionForApiRequest)
guard let url = url as? URL else return
let task = urlSession.dataTask(with: url) _, _, _ in print("DONE")
task.resume()
ios swift unit-testing
I'd recommend watching Testing Tips & Tricks from WWDC 2018. It both talks about testing network code at a higher level and gives concrete examples about using Foundation'sURLProtocolto provide mock data in the tests.
– David Rönnqvist
Mar 22 at 23:27
@DavidRönnqvist Cool, didn't know aboutURLProtocol! Though I don't know what to make of it actually being a class, not a protocol lol
– Alexander
Mar 23 at 0:22
Whats a point of hiding URL with protocol? Looks like over-engineering to me.
– ManWithBear
Mar 23 at 0:59
@Alexander the nameURLProtocolmakes more sense when you realize that it refers to a type of url protocol—for example HTTP (Hypertext Transfer Protocol)—and that it’s not a protocol for things that are URL-like.
– David Rönnqvist
Mar 23 at 2:52
@DavidRönnqvist Ah, makes sense
– Alexander
Mar 23 at 15:59
add a comment |
I am writing some code to be able to make testing easier. After researching, I found a good way of making URLSession testable is to make it conform to a protocol and use that protocol in the class I need to test. I applied the same method to URL. However, I now need to downcast the url parameter as a URL type. This seems a bit "dangerous" to me. What is the proper way to make URL testable? How can I also mock the URLSessionDataTask type returned by dataTask?
import Foundation
protocol URLSessionForApiRequest
func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
protocol URLForApiRequest
init?(string: String)
extension URLSession: URLSessionForApiRequest
extension URL: URLForApiRequest
class ApiRequest
class func makeRequest(url: URLForApiRequest, urlSession: URLSessionForApiRequest)
guard let url = url as? URL else return
let task = urlSession.dataTask(with: url) _, _, _ in print("DONE")
task.resume()
ios swift unit-testing
I am writing some code to be able to make testing easier. After researching, I found a good way of making URLSession testable is to make it conform to a protocol and use that protocol in the class I need to test. I applied the same method to URL. However, I now need to downcast the url parameter as a URL type. This seems a bit "dangerous" to me. What is the proper way to make URL testable? How can I also mock the URLSessionDataTask type returned by dataTask?
import Foundation
protocol URLSessionForApiRequest
func dataTask(with url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask
protocol URLForApiRequest
init?(string: String)
extension URLSession: URLSessionForApiRequest
extension URL: URLForApiRequest
class ApiRequest
class func makeRequest(url: URLForApiRequest, urlSession: URLSessionForApiRequest)
guard let url = url as? URL else return
let task = urlSession.dataTask(with: url) _, _, _ in print("DONE")
task.resume()
ios swift unit-testing
ios swift unit-testing
asked Mar 22 at 23:14
TalhaTalha
49429
49429
I'd recommend watching Testing Tips & Tricks from WWDC 2018. It both talks about testing network code at a higher level and gives concrete examples about using Foundation'sURLProtocolto provide mock data in the tests.
– David Rönnqvist
Mar 22 at 23:27
@DavidRönnqvist Cool, didn't know aboutURLProtocol! Though I don't know what to make of it actually being a class, not a protocol lol
– Alexander
Mar 23 at 0:22
Whats a point of hiding URL with protocol? Looks like over-engineering to me.
– ManWithBear
Mar 23 at 0:59
@Alexander the nameURLProtocolmakes more sense when you realize that it refers to a type of url protocol—for example HTTP (Hypertext Transfer Protocol)—and that it’s not a protocol for things that are URL-like.
– David Rönnqvist
Mar 23 at 2:52
@DavidRönnqvist Ah, makes sense
– Alexander
Mar 23 at 15:59
add a comment |
I'd recommend watching Testing Tips & Tricks from WWDC 2018. It both talks about testing network code at a higher level and gives concrete examples about using Foundation'sURLProtocolto provide mock data in the tests.
– David Rönnqvist
Mar 22 at 23:27
@DavidRönnqvist Cool, didn't know aboutURLProtocol! Though I don't know what to make of it actually being a class, not a protocol lol
– Alexander
Mar 23 at 0:22
Whats a point of hiding URL with protocol? Looks like over-engineering to me.
– ManWithBear
Mar 23 at 0:59
@Alexander the nameURLProtocolmakes more sense when you realize that it refers to a type of url protocol—for example HTTP (Hypertext Transfer Protocol)—and that it’s not a protocol for things that are URL-like.
– David Rönnqvist
Mar 23 at 2:52
@DavidRönnqvist Ah, makes sense
– Alexander
Mar 23 at 15:59
I'd recommend watching Testing Tips & Tricks from WWDC 2018. It both talks about testing network code at a higher level and gives concrete examples about using Foundation's
URLProtocol to provide mock data in the tests.– David Rönnqvist
Mar 22 at 23:27
I'd recommend watching Testing Tips & Tricks from WWDC 2018. It both talks about testing network code at a higher level and gives concrete examples about using Foundation's
URLProtocol to provide mock data in the tests.– David Rönnqvist
Mar 22 at 23:27
@DavidRönnqvist Cool, didn't know about
URLProtocol! Though I don't know what to make of it actually being a class, not a protocol lol– Alexander
Mar 23 at 0:22
@DavidRönnqvist Cool, didn't know about
URLProtocol! Though I don't know what to make of it actually being a class, not a protocol lol– Alexander
Mar 23 at 0:22
Whats a point of hiding URL with protocol? Looks like over-engineering to me.
– ManWithBear
Mar 23 at 0:59
Whats a point of hiding URL with protocol? Looks like over-engineering to me.
– ManWithBear
Mar 23 at 0:59
@Alexander the name
URLProtocol makes more sense when you realize that it refers to a type of url protocol—for example HTTP (Hypertext Transfer Protocol)—and that it’s not a protocol for things that are URL-like.– David Rönnqvist
Mar 23 at 2:52
@Alexander the name
URLProtocol makes more sense when you realize that it refers to a type of url protocol—for example HTTP (Hypertext Transfer Protocol)—and that it’s not a protocol for things that are URL-like.– David Rönnqvist
Mar 23 at 2:52
@DavidRönnqvist Ah, makes sense
– Alexander
Mar 23 at 15:59
@DavidRönnqvist Ah, makes sense
– Alexander
Mar 23 at 15:59
add a comment |
1 Answer
1
active
oldest
votes
You want to make a protocol that wraps the function that you are going to call, then make a concrete implementation and mock implementation that returns whatever you initialize it with. Here is an example:
import UIKit
import PlaygroundSupport
protocol RequestProvider
func request(from: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
class ApiRequest: RequestProvider
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
URLSession.shared.dataTask(with: url, completionHandler: completion).resume
class MockApiRequest: RequestProvider
enum Response
case value(Data, URLResponse), error(Error)
private let response: Response
init(response: Response)
self.response = response
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
switch response
case .value(let data, let response):
completion(data, response, nil)
case .error(let error):
completion(nil, nil, error)
class SomeClassThatMakesAnAPIRequest
private let requestProvider: RequestProvider
init(requestProvider: RequestProvider)
self.requestProvider = requestProvider
//Use the requestProvider here and it uses either the Mock or the "real" API provider based don what you injected
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55308950%2fhow-to-mock-url-struct%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
You want to make a protocol that wraps the function that you are going to call, then make a concrete implementation and mock implementation that returns whatever you initialize it with. Here is an example:
import UIKit
import PlaygroundSupport
protocol RequestProvider
func request(from: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
class ApiRequest: RequestProvider
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
URLSession.shared.dataTask(with: url, completionHandler: completion).resume
class MockApiRequest: RequestProvider
enum Response
case value(Data, URLResponse), error(Error)
private let response: Response
init(response: Response)
self.response = response
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
switch response
case .value(let data, let response):
completion(data, response, nil)
case .error(let error):
completion(nil, nil, error)
class SomeClassThatMakesAnAPIRequest
private let requestProvider: RequestProvider
init(requestProvider: RequestProvider)
self.requestProvider = requestProvider
//Use the requestProvider here and it uses either the Mock or the "real" API provider based don what you injected
add a comment |
You want to make a protocol that wraps the function that you are going to call, then make a concrete implementation and mock implementation that returns whatever you initialize it with. Here is an example:
import UIKit
import PlaygroundSupport
protocol RequestProvider
func request(from: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
class ApiRequest: RequestProvider
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
URLSession.shared.dataTask(with: url, completionHandler: completion).resume
class MockApiRequest: RequestProvider
enum Response
case value(Data, URLResponse), error(Error)
private let response: Response
init(response: Response)
self.response = response
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
switch response
case .value(let data, let response):
completion(data, response, nil)
case .error(let error):
completion(nil, nil, error)
class SomeClassThatMakesAnAPIRequest
private let requestProvider: RequestProvider
init(requestProvider: RequestProvider)
self.requestProvider = requestProvider
//Use the requestProvider here and it uses either the Mock or the "real" API provider based don what you injected
add a comment |
You want to make a protocol that wraps the function that you are going to call, then make a concrete implementation and mock implementation that returns whatever you initialize it with. Here is an example:
import UIKit
import PlaygroundSupport
protocol RequestProvider
func request(from: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
class ApiRequest: RequestProvider
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
URLSession.shared.dataTask(with: url, completionHandler: completion).resume
class MockApiRequest: RequestProvider
enum Response
case value(Data, URLResponse), error(Error)
private let response: Response
init(response: Response)
self.response = response
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
switch response
case .value(let data, let response):
completion(data, response, nil)
case .error(let error):
completion(nil, nil, error)
class SomeClassThatMakesAnAPIRequest
private let requestProvider: RequestProvider
init(requestProvider: RequestProvider)
self.requestProvider = requestProvider
//Use the requestProvider here and it uses either the Mock or the "real" API provider based don what you injected
You want to make a protocol that wraps the function that you are going to call, then make a concrete implementation and mock implementation that returns whatever you initialize it with. Here is an example:
import UIKit
import PlaygroundSupport
protocol RequestProvider
func request(from: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
class ApiRequest: RequestProvider
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
URLSession.shared.dataTask(with: url, completionHandler: completion).resume
class MockApiRequest: RequestProvider
enum Response
case value(Data, URLResponse), error(Error)
private let response: Response
init(response: Response)
self.response = response
func request(from url: URL, completion: @escaping (Data?, URLResponse?, Error?) -> Void)
switch response
case .value(let data, let response):
completion(data, response, nil)
case .error(let error):
completion(nil, nil, error)
class SomeClassThatMakesAnAPIRequest
private let requestProvider: RequestProvider
init(requestProvider: RequestProvider)
self.requestProvider = requestProvider
//Use the requestProvider here and it uses either the Mock or the "real" API provider based don what you injected
answered Mar 23 at 0:46
Josh HomannJosh Homann
9,35211422
9,35211422
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55308950%2fhow-to-mock-url-struct%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I'd recommend watching Testing Tips & Tricks from WWDC 2018. It both talks about testing network code at a higher level and gives concrete examples about using Foundation's
URLProtocolto provide mock data in the tests.– David Rönnqvist
Mar 22 at 23:27
@DavidRönnqvist Cool, didn't know about
URLProtocol! Though I don't know what to make of it actually being a class, not a protocol lol– Alexander
Mar 23 at 0:22
Whats a point of hiding URL with protocol? Looks like over-engineering to me.
– ManWithBear
Mar 23 at 0:59
@Alexander the name
URLProtocolmakes more sense when you realize that it refers to a type of url protocol—for example HTTP (Hypertext Transfer Protocol)—and that it’s not a protocol for things that are URL-like.– David Rönnqvist
Mar 23 at 2:52
@DavidRönnqvist Ah, makes sense
– Alexander
Mar 23 at 15:59