apple / swift-openapi-generator

Generate Swift client and server code from an OpenAPI document.
https://swiftpackageindex.com/apple/swift-openapi-generator/documentation
Apache License 2.0
1.21k stars 87 forks source link

How to send invalid data with the client to test negative scenarios? #521

Closed mapedd closed 3 months ago

mapedd commented 3 months ago

Question

Hi all I'd like to write a test, that verifies that my Swift Code generated API will return a 400 error, when data sent to the sever is not valid.

I'd prefer to use client code generated by swift code gen too but how can I do it?

code path I want to test in my server implementation:

    guard let storeType = createStoreRequest.storeType.asLocalStoreType else {
      return .badRequest(.init())
    }

basically check that I can map the enum from API to local one

my test code :

 func createStoreReturns400OnUnsupportedStoreType() async throws {
    try await signInGetUserDetails()

    let createStoreRequest = Components.Schemas.CreateStoreRequest(
      name: "Something",
      address: "address",
      addressHint: nil,
      location: Components.Schemas.Coordinates.init(latitude: 123, longitude: 123),
      openingHours: [],
      storeType: Components.Schemas.StoreType(rawValue: "UNSUPPORTED_STORE_TYPE")! // <-- how to create CreateStoreRequest or use client to send "invalid" data?
    )
    let newStoreOutput = try await client.createStore(.init(body: .json(createStoreRequest)))

    // so that I can verify, that I receive badRequest output?
    _ = try newStoreOutput.badRequest

  }
}
czechboy0 commented 3 months ago

If you want to test your server implementation (the type that conforms to APIProtocol), you can write tests like this: https://github.com/apple/swift-openapi-generator/blob/main/Examples/hello-world-vapor-server-example/Tests/HelloWorldVaporServerTests/HelloWorldVaporServerTests.swift

While the example is specific to Vapor, notice that the test itself is web framework-agnostic, the file doesn't even import Vapor.

mapedd commented 3 months ago

My goal to write a integration test (not a unit test that just calls methods without real network) that sends actual network request, and I'm just wondering, if it's possible to send invalid data using the client code generated by the Swift Code gen?

czechboy0 commented 3 months ago

Depends on what you mean by "invalid". If you mean malformed JSON, then the answer is no (unless you write a middleware that malforms the outgoing requests, I guess that'd work). If you mean that e.g. the server expects a string with a certain prefix and that prefix is missing, then yes, but that's purely application-logic semantics.

If you want to test how your server is performing fully integrated, maybe use something like XCTVapor (if you're using Vapor) or whatever web framework you use. That should allow you to send completely arbitrary requests and verify that your server behaves as expected.

mapedd commented 3 months ago

unless you write a middleware that malforms the outgoing requests

seems to be this could work and would be the easiest , thanks!

maybe use something like XCTVapor (i Of course there are thousands other possibilities to do that, my goal is to write as little code apart from code generated as possible

Thanks for help