Как построить интеграционные тесты для приложения Saturn
Я пытаюсь создать несколько интеграционных тестов для небольшого API, построенного с использованием фреймворка Saturn.
API построен с обычным Saturn
Вычислительные выражения, такие как application
, controller
, router
и т.п.
Но для того, чтобы построить интеграционные тесты, я думаю, что нужно заменить application
Вычислительное выражение (ce) и ручная работа WebHostBuilder
, Но как я могу это сделать и настроить для использования маршрутизации, контроллеров и т. Д. API?
мой application
выглядит так:
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" })
}
С router
и на одном из controllers
...
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(apiRouter) \\<-- This appears to be a problem
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(apiRouter)
, apiRouter
определяется в проекте API.
Есть идеи, в чем проблема?
0 ответов
Оказалось, что это не имеет отношения к Saturn
совсем. Все из-за того, чтоF#
инициирует modules
. Ответ можно найти здесь
Как предлагается в упомянутом сообщении. Я просто добавил[<EntryPoint>]
функция и все работало как положено.