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;








0















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()












share|improve this question






















  • 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











  • 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












  • @DavidRönnqvist Ah, makes sense

    – Alexander
    Mar 23 at 15:59

















0















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()












share|improve this question






















  • 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











  • 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












  • @DavidRönnqvist Ah, makes sense

    – Alexander
    Mar 23 at 15:59













0












0








0








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()












share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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'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











  • 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












  • @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












  • @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 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
















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












1 Answer
1






active

oldest

votes


















0














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






share|improve this answer























    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
    );



    );













    draft saved

    draft discarded


















    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









    0














    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






    share|improve this answer



























      0














      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






      share|improve this answer

























        0












        0








        0







        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






        share|improve this answer













        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







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Mar 23 at 0:46









        Josh HomannJosh Homann

        9,35211422




        9,35211422





























            draft saved

            draft discarded
















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Obelisk of Theodosius Contents History Description Notes Bibliography Further reading External links Navigation menuAge of spirituality : late antique and early Christian art, third to seventh centuryOver 60 picturesObelisks of the World41°00′21.24″N 28°58′31.43″E / 41.0059000°N 28.9753972°E / 41.0059000; 28.97539727724550-7235741376235741376

            밀양 대씨 역사 각주 함께 보기 둘러보기 메뉴밀양 대씨

            1973년 목차 사건 문화 탄생 사망 노벨상 달력 둘러보기 메뉴