Testing in Vapor | raywenderlich.com

Use a pre-built Vapor application to learn both how to test your server-side Swift Vapor apps on macOS and also best practices to simplify your test code.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/1002044-testing-in-vapor

@0xtim Hi, please help. Don’t understand how to test ws. I wrote microservise that returns data via ws. I want to create test that ws returns correct data. Problem is that I don’t understand how to connect to ws in test case that was created by the app.
This is how I do it:
` public func configure(_ config: inout Config, _ env: inout Environment, _ services: inout Services) throws {
// Register providers first
try services.register(FluentSQLiteProvider())

  try services.register(LeafProvider())
  config.prefer(LeafRenderer.self, for: ViewRenderer.self)

    // Register routes to the router
    let router = EngineRouter.default()
    try routes(router)
    services.register(router, as: Router.self)

    // Register middleware
    var middlewares = MiddlewareConfig() // Create _empty_ middleware config
    // middlewares.use(FileMiddleware.self) // Serves files from `Public/` directory
    middlewares.use(ErrorMiddleware.self) // Catches errors and converts to HTTP response
    services.register(middlewares)
  
  let websockets = NIOWebSocketServer.default()
  sockets(websockets)
  services.register(websockets, as: WebSocketServer.self)

}

//////
public func sockets(_ websockets: NIOWebSocketServer) {
// Status

      let onTextHandler = { (ws: WebSocket, text: String) in
        if let jsonData = text.data(using: .utf8), let exchangesToListen = try? JSONDecoder().decode(ExchangesToListen.self, from: jsonData) {
          operationManager.updateExchangesToListen(exchangesToListen: exchangesToListen)
          ws.send("Did get")
        } else {
          let errorText = "Can't parse JSON to \(ExchangesToListen.self) from: \(text)"
          print(errorText)
          ws.send(errorText)
          return
        }
      }
      
      websockets.get("echo-test") { ws, req in
        print("ws connnected")
        ws.onText { ws, text in
          print("ws received: \(text)")
          ws.send("echo - \(text)")
        }
      }
      
      websockets.get("tickers") { ws, req in
        ws.onText(onTextHandler)
        print("client connected to WS with interval")
        operationManager.sessionManager.add(listener: ws)
      }
      
    }

/////

    extension Application {
  
  static func testable(envArgs: [String]? = nil) throws -> Application {
    var config = Config.default()
    var services = Services.default()
    var env = Environment.testing
    
    if let environmentArgs = envArgs {
      env.arguments = environmentArgs
    }
    
    try App.configure(&config, &env, &services)
    let app = try Application(config: config, environment: env, services: services)
    
    try App.boot(app)
    return app
  }
  
  
  func createWs() -> EventLoopFuture<WebSocket> {
    let responder = try! self.make(WebSocketClient.self)
    let request = HTTPRequest(url: URL(string: "ws://127.0.0.1:8080/tickers/")!)
    let wrappedRequest = Request(http: request, using: self)
    return responder.webSocketConnect(wrappedRequest)
  }`

And test case:
`f unc testTickersCanBeRetrievedFromWsAPI() throws {

    let jsonString = "{\"interval\":10, \"exchanges\":[{\"exchangeName\":\"Binance\", \"pairs\":[\"LTC-BTC\"] } ] }"
    let expectation = self.expectation(description: "")
    let _ = self.app.createWs().do { (ws) in
      ws.send(jsonString)
      ws.onText { ws, text in
        print(text)
        XCTAssert(text.count > 0)
        expectation.fulfill()
      }
      }.catch { (error) in
        print(error)
    }
    waitForExpectations(timeout: 10, handler: nil)
    
  }`

Hmm web socket tests are going to be difficult and not something I’ve really looked at. I would take a look at the way the WebSockets are tested in NIO, they’re probably a good place to start

This tutorial is more than six months old so questions are no longer supported at the moment for it. Thank you!