Guard let fakeUrl = Bundle(for: ..) retourne nil ? Résolu :)

Salut Bob,

Après plusieurs heures de recherches, je jette j’éponge et fais appel à la communauté.

Qu’est qui peut faire que le guard ci-dessous, dans un contexte de tests retourne nil.

Bien sûr j’ai tout vérifié, essayé, remplacer, dupliquer, re-saisi, … J’ai 2 projets identiques, 1 qui marche, celui-ci non, j’ai beau tenter de recouper, stackoverflowter, niet, xcode ne veut rien savoir?!
Sûr qu’il y a un lézard, mais où ?
A la limite, corriger l’erreur m’importe moins que de comprendre ce qui se passe. En effet le projet marche chez l’élève, mais pas chez moi (même versions ios et xcode), c’est encore plus déroutant.

J’ajoute que tous les tests passent, sauf celui faisant précisément appel au fichier json convoité, fake d’une réponse correcte.

guard let fakeUrl = Bundle(for: FakeWeatherResponseNetwork.self).url(forResource: "Weather", withExtension: "json") else {fatalError("erreur !")}

Des suggestions ? Je prends ! Merci :slight_smile:

J’enrichie les pièces à convictions :

Le test unitaire :

    func test_4_GetWeatherShouldPostFailedCallbackIfAllOK() {
        //Given
        let weatherService = WeatherService(weatherSession: WeatherURLSessionFake(data: FakeWeatherResponseNetwork.weatherJsonOK, response: FakeWeatherResponseNetwork.responseOK, error: nil))
        //When
        let expectation = XCTestExpectation(description: "Wait for queue change")
        weatherService.getWeather(city: "test") { success, weatherResult in
            
            //Then
            XCTAssertFalse(success)
            XCTAssertNil(weatherResult)
            expectation.fulfill()
        }
        wait(for: [expectation], timeout: 0.01)
    }

La classe FakeWeatherResponseNetwork :

class FakeWeatherResponseNetwork {
    
    static let responseOK = HTTPURLResponse(url: URL(string: "http://openclassrooms.com")!, statusCode: 200, httpVersion: nil, headerFields: nil)!
    
    static let responseKO = HTTPURLResponse(url: URL(string: "http://openclassrooms.com")!, statusCode: 500, httpVersion: nil, headerFields: nil)!
    
    class WeatherError: Error {}
    static let error = WeatherError()
    
    static var weatherJsonOK: Data {
        let bundle = Bundle(for: FakeWeatherResponseNetwork.self)
        let fakeUrl = bundle.url(forResource: "Weather", withExtension: "json")
        
        if let zUrl = fakeUrl {
            print("##### \(zUrl) #####")
        } else {
            print("##### t'es mauvais ! #####")
        }
                
        let data = try! Data(contentsOf: fakeUrl!)
                
        return data
    } // static var weatherCorrectData
    
    static let weatherIncorrectData = "erreur".data(using: .utf8)!
}

Le log console :

Test Case '-[P9_Le_BaluchonTests.WeatherServiceTestCase test_4_GetWeatherShouldPostFailedCallbackIfAllOK]' started.
##### t'es mauvais ! #####
P9_Le_BaluchonTests/FakeWeatherResponseNetwork.swift:29: Fatal error: Unexpectedly found nil while unwrapping an Optional value
2022-10-27 21:18:24.309163+0200 P9_Le_Baluchon[17677:550167] P9_Le_BaluchonTests/FakeWeatherResponseNetwork.swift:29: Fatal error: Unexpectedly found nil while unwrapping an Optional value
(lldb) 

Le if let zUrl = fakeUrl me dit bien que je suis mauvais, mais j’aimerais bien savoir pourquoi ?

Pour info : L’exact même code sur le projet parallèle, me donne en console :

Test Case '-[P9_Le_BaluchonTests.WeatherServiceTestCase testGetWeather_ShouldPostSucessCallbackIfAllOK]' started.
##### file:///Users/jean-michelzaragoza/Library/Developer/CoreSimulator/Devices/48D66203-F92A-42AA-A6F3-E9C0EA952F69/data/Containers/Bundle/Application/7F6FC4A3-085D-4CE8-B146-9C5F005DB395/P9_Le_Baluchon.app/PlugIns/P9_Le_BaluchonTests.xctest/Weather.json #####

Sacrée URL pour un fichier qui est juste à côté, mais il la trouve. Qu’est-ce qui se passe dans l’autre projet ?

Encore plus fort !!!

J’ai purement et simplement copiè-collé la classe FakeWeatherResponseNetwork du projet qui marche sur celui qui ne marche pas. Le log console confirme bien :

Test Case '-[P9_Le_BaluchonTests.WeatherServiceTestCase test_4_GetWeatherShouldPostFailedCallbackIfAllOK]' started.
**##### t'es mauvais ! #####** 
P9_Le_BaluchonTests/FakeWeatherResponseNetwork.swift:29: Fatal error: Unexpectedly found nil while unwrapping an Optional value
2022-10-27 21:41:42.439979+0200 P9_Le_Baluchon[18330:572125] P9_Le_BaluchonTests/FakeWeatherResponseNetwork.swift:29: Fatal error: Unexpectedly found nil while unwrapping an Optional value

Je reste à l’écoute. Merci :pensive:

AUTO REPONSE :

Salut Bob,

L’élève a créé son fichier json Fake, dans le groupe Tests (théoriquement le Bundle, c’est à dire le container des fichiers de tests).

Sauf que :

Confirm that the resource is added to the test target.

Ce qui n’avait pas été fait. Pourquoi, moi pas savoir :slight_smile:

Le problème a été résolu en quelques secondes.

Ça pourra peut-être servir à d’autres.

Bien à vous.

1 « J'aime »