Now that our API Client is all set up and good to go, we can start testing. To this end, we define a new test class "OxfordAPIClientAsynchonrousTests" to test our API client methods. Our test class will conform to the OxfordAPIDictionaryAPIDelegate protocol, whose methods are implemented below. In addition, we define a promise variable for the class, as well as a computed property for the API client singleton so that it can be accessed more quickly in code. In addition, we implement the setUp() method such that the singleton's delegate is set to the test class rather than being set to the singleton itself. The tearDown() method will reverse these actions, setting the promise to null and resetting the API client singleton's delegate so that the singleton itself acts as the delegate.

    import XCTest

@testable import Scrambled_Messenger

/** Each test should be run individually **/

class OxfordAPIClientAsynchronousTests: XCTestCase, OxfordDictionaryAPIDelegate {
    
    typealias JSONResponse = [String: Any]

    var promise: XCTestExpectation!

    var sharedClient: OxfordAPIClient{
        return OxfordAPIClient.sharedClient
    }
    
    override func setUp() {
        
        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)
        
        super.setUp()
        
        // Put setup code here. This method is called before the invocation of each test method in the class.
        
    }
    
    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        
        sharedClient.resetDefaultDelegate()
        
        promise = nil
        
        super.tearDown()
    }
}

For our testing to be carried out more smoothly, our we'll make our test class conform to the OxfordAPIClientDelegate protocol and implement all of the delegate methods, as show below:



    func didFailToConnectToEndpoint(withError error: Error) {
        XCTFail("Error occurred while attempting to connect to the server: \(error.localizedDescription)")

    }
    
    /** Proper credentials are provided, the API request can be authenticated; an HTTP Response is received but no data is provided **/
    
    
    func didFailToGetJSONData(withHTTPResponse httpResponse: HTTPURLResponse) {
        XCTFail("Unable to get JSON data with http status code: \(httpResponse.statusCode)")

    }
    
    /** Proper credentials are provided, and the API request is fully authenticated; an HTTP Response is received and the data is provided by the raw data could not be parsed into a JSON object **/
    
    func didFailToSerializeJSONData(withHTTPResponse httpResponse: HTTPURLResponse) {
        XCTFail("Unable to serialize the data into a json response, http status code: \(httpResponse.statusCode)")

    }
    
    
    
    /** If erroneous credentials are provided, the API request can't be authenticated; an HTTP Response is received but no data is provided **/
    

    func didFinishReceivingHTTPResponse(withHTTPResponse httpResponse: HTTPURLResponse) {
        XCTFail("HTTP response received with status code: \(httpResponse.statusCode)")

    }
    
    /** Proper credentials are provided, and the API request is fully authenticated; an HTTP Response is received and serialized JSON data is provided **/
    
    func didFinishReceivingJSONData(withJSONResponse jsonResponse: OxfordDictionaryAPIDelegate.JSONResponse, withHTTPResponse httpResponse: HTTPURLResponse) {
        
        promise.fulfill()
        print("JSON response is as follows: \(jsonResponse)")
    }
    
   
    

Note that for each of the delegate methods above, with the exception of didFinishReceivingJSONData(withJSONResponse:withHTTPResponse), XCTFail() is called to indicate that the test failed. By contrast, for the didFinishReceivingJSONData(withJSONResponse:withHTTPResponse) method, we call fulfill on the promise object defined for the class. Tests can be designed for all kinds of purposes. In this case, we define tests whose success is determined based on whether or not parsed JSON data has been received as result of calling our publicly-acessible API client methods.

Finally comes the tests themselves. For each of the publicly available methods provided by the API client we run a corresponding test. Success occurs when the promise is fulfilled, which in this case occurs when the delegate method didFinishReceivingJSONData(withJSONResponse:withHTTPResponse) is called, while failure indicated anytime any of the other delegate methods are called.

	

    
    func testWordListAPIRequesWithValidationt(){
        
        promise = expectation(description: "Promise fulfilled: JSON data for example sentences API request received and serialized successfully, http status code: 200")
        
        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)
        
        
        
        sharedClient.downloadWordlistJSONDataWithValidation(forFilters: [
            OxfordAPIEndpoint.OxfordAPIFilter.registers([
                OxfordLanguageRegister.archaic.rawValue
                ])
            ])
        
        waitForExpectations(timeout: 20.00, handler: nil)
        
    }
    
    func testWordListWithRegisterAndRegionFiltersAPIRequest(){
        
        
        promise = expectation(description: "Promise fulfilled: JSON data for example sentences API request received and serialized successfully, http status code: 200")
        
        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)
        
        
        
        sharedClient.downloadWordListJSONData(
            forDomainFilters: [],
            forRegionFilters: [OxfordAPIEndpoint.OxfordAPIFilter.regions([OxfordRegion.us.rawValue])],
            forRegisterFilters: [OxfordAPIEndpoint.OxfordAPIFilter.registers([OxfordLanguageRegister.dialect.rawValue])],
            forTranslationFilters: [],
            forLexicalCategoryFilters: [])
        
        waitForExpectations(timeout: 20.00, handler: nil)
        
    }
    
    
    
    func testWordListWithRegisterFiltersAPIRequest(){
        
        
        promise = expectation(description: "Promise fulfilled: JSON data for example sentences API request received and serialized successfully, http status code: 200")
        
        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)
        
        
        
        sharedClient.downloadWordListJSONData(
            forDomainFilters: [],
            forRegionFilters: [],
            forRegisterFilters: [OxfordAPIEndpoint.OxfordAPIFilter.registers([OxfordLanguageRegister.army_slang.rawValue])],
            forTranslationFilters: [],
            forLexicalCategoryFilters: [])
        
        waitForExpectations(timeout: 20.00, handler: nil)
        
    }
    
    func testWordListWithDomainFiltersAPIRequest(){
        
        
        promise = expectation(description: "Promise fulfilled: JSON data for example sentences API request received and serialized successfully, http status code: 200")
        
        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)
        
    
        
        sharedClient.downloadWordListJSONData(
            forDomainFilters: [OxfordAPIEndpoint.OxfordAPIFilter.domains([OxfordDomain.anatomy.rawValue])],   forRegionFilters: [],
            forRegisterFilters: [],
          forTranslationFilters: [],
          forLexicalCategoryFilters: [])
        
        waitForExpectations(timeout: 20.00, handler: nil)

    }
    
    func testDictionaryEntryWithRegionFiltersAPIRequest() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
        
        
        promise = expectation(description: "Promise fulfilled: JSON data for example sentences API request received and serialized successfully, http status code: 200")
        
        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)
       
        sharedClient.downloadDictionaryEntryJSONData(forWord: "love", withFilters: [OxfordAPIEndpoint.OxfordAPIFilter.regions([OxfordRegion.us.rawValue])])
        
        waitForExpectations(timeout: 20.00, handler: nil)
        
        
    }
    
    
    func testExampleSentencesAPIRequest() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
        

        promise = expectation(description: "Promise fulfilled: JSON data for example sentences API request received and serialized successfully, http status code: 200")

        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)

        sharedClient.downloadExampleSentencesJSONData(forWord: "love")
        
        waitForExpectations(timeout: 20.00, handler: nil)

        

        
    }
    
    func testAntonymsAndSynonymsAPIRequest() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
        
        promise = expectation(description: "Promise fulfilled: JSON data for antonym and synonym API request received and serialized successfully, http status code: 200")

        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)


        sharedClient.downloadThesaurusJSONData(forWord: "love", withAntonyms: true, withSynonyms: true)
        
        waitForExpectations(timeout: 20.00, handler: nil)

    }
    
    
    func testSynonymsAPIRequest() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
        
        promise = expectation(description: "Promise fulfilled: JSON data for synonym API request received and serialized successfully, http status code: 200")

        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)

        sharedClient.downloadThesaurusJSONData(forWord: "love", withAntonyms: false, withSynonyms: true)
        
        waitForExpectations(timeout: 20.00, handler: nil)
    }
    
    func testAntonymsAPIRequest() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
        
        promise = expectation(description: "Promise fulfilled: JSON data for antonym API request received and serialized successfully, http status code: 200")

        sharedClient.setOxfordDictionaryAPIClientDelegate(with: self)

        sharedClient.downloadThesaurusJSONData(forWord: "love", withAntonyms: true, withSynonyms: false)
        
        waitForExpectations(timeout: 20.00, handler: nil)
    }
    
    

Please note that this test class is designed such that each test must be run independently of one another. Do not attempt to run all the tests at once simultaneously, since these are asynchronous methods and such testing can result bugs.

Having tested our API client class, we should also test our OxfordAPIRequest struct to make sure that it is functioning properly, as its functionality is integral for the success of our API client class.

To continue, please click here

If you feel confused or are having trouble following, you can go back to the previous page or back to the table of contents table of contents.