【问题标题】:How to build integrations tests for a Saturn app如何为 Saturn 应用程序构建集成测试
【发布时间】:2019-06-01 11:19:47
【问题描述】:

我正在尝试为使用 Saturn framework 构建的小型 API 构建一些集成测试。

API 是使用常用的Saturn 计算表达式构建的,例如applicationcontrollerrouter 等。

但为了构建集成测试,我需要替换 application 计算表达式 (ce) 并手工制作 WebHostBuilder

我的applicationce 看起来像这样:

module Server 

let app =
    application {
        url ("http://0.0.0.0:" + port.ToString() + "/")
        use_router apiRouter
        memory_cache
        service_config configureSerialization
        use_gzip
        use_config (fun _ ->
            System.Environment.CurrentDirectory <- (System.Reflection.Assembly.GetExecutingAssembly()).Location
                                                   |> Path.GetDirectoryName
            let configurationRoot =
                ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("appSettings.json")
                    .Build()
            let appConfig = FsConfig.AppConfig(configurationRoot)

            let dbPath =
                match appConfig.Get<AppSettings>() with
                | Ok settings when settings.DbConfig.Database.Contains(":memory:") -> settings.DbConfig.Database
                | Ok settings -> Path.Combine(System.Environment.CurrentDirectory, settings.DbConfig.Database)
                | Error _ -> failwithf "Invalid database path"
            { connectionString = dbPath |> sprintf "DataSource=%s;Version=3" })
    } 

使用routercontrollers 之一...

let cartController =
    controller {
        create createCartAction
        show getCartAction
        delete deleteCartAction
        subController "/items" cartItemsController
    }

let apiRouter =
    router {
        not_found_handler (setStatusCode 404 >=> text "Not found")
        pipe_through apiPipeline
        forward "/cart" cartController
    }

上面的代码在我的 API 项目中,下面带有集成测试的代码在第二个项目中。后者对前者有项目引用。

let configureApp (app : IApplicationBuilder) =
    app.UseGiraffe(Server.apiRouter) \\<-- The problem is here. Server.apiRouter is null!

let configureServices (services : IServiceCollection) =
    services.AddGiraffe() |> ignore

let builder = WebHostBuilder()
                .UseContentRoot(contentRoot) 
                .Configure(Action<IApplicationBuilder> configureApp)
                .ConfigureServices(configureServices)

let testServer = new TestServer(builder)

let client = testServer.CreateClient()

let! response = client.GetAsync "/"

test <@ HttpStatusCode.OK = response.StatusCode @> 

当测试运行时,它会失败并出现以下异常:

System.InvalidOperationException' occurred in System.Private.CoreLib.dll but was not handled in user code: 'A suitable constructor for type 'Giraffe.Middleware+GiraffeMiddleware' could not be located. Ensure the type is concrete and services are registered for all parameters of a public constructor.' 

问题似乎出在app.UseGiraffe(Server.apiRouter) 行上。 apiRouter 是在 API 项目的 Server 模块中定义的——但是当这段代码在测试项目中运行时,Server.apiRouternull

但是,如果我将测试代码移动到与 API 相同的项目中 - 测试可以完美运行。

如果从测试项目中调用,为什么apiRouter 计算表达式会是null

【问题讨论】:

    标签: f# saturn-framework


    【解决方案1】:

    原来这和Saturn一点关系都没有。这一切都与F# 发起modules 的方式有关。 The answer can be found here

    正如参考帖子中所建议的那样。我只是添加了一个[&lt;EntryPoint&gt;] 函数,一切都按预期工作。

    【讨论】:

      猜你喜欢
      • 2019-05-30
      • 1970-01-01
      • 2021-05-16
      • 2013-10-05
      • 1970-01-01
      • 2015-02-12
      • 1970-01-01
      • 2010-10-20
      • 2020-12-13
      相关资源
      最近更新 更多