Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions TUnit.Templates.Tests/AspNetTemplateTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@
{
await Engine.Execute(Options).ConfigureAwait(false);
}

[Test]
public async Task InstantiationTestWithFSharp()
{
TemplateShortName = "TUnit.AspNet.FSharp";

Check warning on line 16 in TUnit.Templates.Tests/AspNetTemplateTests.cs

View workflow job for this annotation

GitHub Actions / modularpipeline (ubuntu-latest)

Test methods should not assign instance data

Check warning on line 16 in TUnit.Templates.Tests/AspNetTemplateTests.cs

View workflow job for this annotation

GitHub Actions / modularpipeline (ubuntu-latest)

Test methods should not assign instance data

Check warning on line 16 in TUnit.Templates.Tests/AspNetTemplateTests.cs

View workflow job for this annotation

GitHub Actions / modularpipeline (windows-latest)

Test methods should not assign instance data

Check warning on line 16 in TUnit.Templates.Tests/AspNetTemplateTests.cs

View workflow job for this annotation

GitHub Actions / modularpipeline (windows-latest)

Test methods should not assign instance data

Check warning on line 16 in TUnit.Templates.Tests/AspNetTemplateTests.cs

View workflow job for this annotation

GitHub Actions / modularpipeline (macos-latest)

Test methods should not assign instance data

Check warning on line 16 in TUnit.Templates.Tests/AspNetTemplateTests.cs

View workflow job for this annotation

GitHub Actions / modularpipeline (macos-latest)

Test methods should not assign instance data
await Engine.Execute(Options).ConfigureAwait(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TUnit.AspNet.FSharp

// Here you could define global logic that would affect all tests

// You can use attributes at the assembly level to apply to all tests in the assembly
[<assembly: System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage>]
do ()
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="1.0.0" />
<PackageReference Include="TUnit" Version="1.0.0" />
<PackageReference Include="TUnit.Assertions.FSharp" Version="1.0.0" />
</ItemGroup>

<ItemGroup>
<Compile Include="WebApplicationFactory.fs" />
<Compile Include="GlobalSetup.fs" />
<Compile Include="Tests.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\WebApp\WebApp.fsproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace TUnit.AspNet.FSharp

open System
open System.Threading.Tasks
open TUnit
open TUnit.Core
open TUnit.Assertions
open TUnit.Assertions.FSharp.Operations
open TUnit.Assertions.Extensions

type Tests() =

[<ClassDataSource(typeof<WebApplicationFactory>, Shared = SharedType.PerTestSession)>]
member val public WebApplicationFactory: WebApplicationFactory = Unchecked.defaultof<WebApplicationFactory> with get, set

[<Test>]
member this.Test() =
async {
let client = this.WebApplicationFactory.CreateClient()
let! response = client.GetAsync("/ping") |> Async.AwaitTask
let! stringContent = response.Content.ReadAsStringAsync() |> Async.AwaitTask
do! check (Assert.That<string>(stringContent).IsEqualTo("Hello, World!"))
}

[<Test>]
member this.GetWeatherForecast() =
async {
let client = this.WebApplicationFactory.CreateClient()
let! response = client.GetAsync("/weatherforecast") |> Async.AwaitTask
let! stringContent = response.Content.ReadAsStringAsync() |> Async.AwaitTask
do! check (Assert.That<string>(stringContent).IsNotNullOrEmpty())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace TUnit.AspNet.FSharp

open System.Threading.Tasks
open Microsoft.AspNetCore.Mvc.Testing
open TUnit.Core.Interfaces

type WebApplicationFactory() =
inherit WebApplicationFactory<WebApp.Program.Program>()

interface IAsyncInitializer with
member this.InitializeAsync() : Task =
let _ = this.Server
Task.CompletedTask


Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace WebApp.Controllers

open System
open System.Collections.Generic
open System.Linq
open System.Threading.Tasks
open Microsoft.AspNetCore.Mvc
open Microsoft.Extensions.Logging
open WebApp

[<ApiController>]
[<Route("[controller]")>]
type WeatherForecastController (logger : ILogger<WeatherForecastController>) =
inherit ControllerBase()

let summaries =
[|
"Freezing"
"Bracing"
"Chilly"
"Cool"
"Mild"
"Warm"
"Balmy"
"Hot"
"Sweltering"
"Scorching"
|]

[<HttpGet>]
member _.Get() =
let rng = System.Random()
[|
for index in 0..4 ->
{ Date = DateTime.Now.AddDays(float index)
TemperatureC = rng.Next(-20,55)
Summary = summaries.[rng.Next(summaries.Length)] }
|]
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace WebApp
#nowarn "20"
open System
open System.Collections.Generic
open System.IO
open System.Linq
open System.Threading.Tasks
open Microsoft.AspNetCore
open Microsoft.AspNetCore.Builder
open Microsoft.AspNetCore.Hosting
open Microsoft.AspNetCore.HttpsPolicy
open Microsoft.Extensions.Configuration
open Microsoft.Extensions.DependencyInjection
open Microsoft.Extensions.Hosting
open Microsoft.Extensions.Logging

module Program =
type Program = class end
let exitCode = 0

[<EntryPoint>]
let main (args: string[]) =
let builder = WebApplication.CreateBuilder(args)

builder.Services.AddEndpointsApiExplorer() |> ignore

builder.Services.AddControllers() |> ignore

let app = builder.Build()

app.UseHttpsRedirection()

app.UseAuthorization()
app.MapControllers()

app.MapGet("/ping", Func<string>(fun () -> "Hello, World!")) |> ignore

app.Run()

exitCode
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5112",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "https://localhost:7000;http://localhost:5112",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace WebApp

open System

type WeatherForecast =
{ Date: DateTime
TemperatureC: int
Summary: string }

member this.TemperatureF =
32.0 + (float this.TemperatureC / 0.5556)
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<Compile Include="WeatherForecast.fs" />
<Compile Include="Controllers/WeatherForecastController.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "Tom Longhurst",
"description": "A template for testing an ASP.NET Core project with TUnit",
"classifications": [
"Test",
"TUnit",
"Asp",
"ASP.NET"
],
"name": "TUnit ASP.NET Core Project",
"identity": "TUnit.Test.AspNet.FSharp",
"groupIdentity": "TUnit.AspNet",
"shortName": "TUnit.AspNet.FSharp",
"tags": {
"language": "F#",
"type": "project"
},
"sourceName": "TestProject",
"preferNameDirectory": true
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TestProject

// Here you could define global logic that would affect all tests

// You can use attributes at the assembly level to apply to all tests in the assembly
[<assembly: System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage>]
do ()
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.5" />
<PackageReference Include="TUnit" Version="0.21.13" />
<PackageReference Include="TUnit.Assertions.FSharp" Version="0.21.13" />
</ItemGroup>

<ItemGroup>
<Compile Include="WebApplicationFactory.fs" />
<Compile Include="GlobalSetup.fs" />
<Compile Include="Tests.fs" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\WebApp\WebApp.fsproj" />
</ItemGroup>

</Project>
32 changes: 32 additions & 0 deletions TUnit.Templates/content/TUnit.AspNet.FSharp/TestProject/Tests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace TestProject

open System
open System.Threading.Tasks
open TUnit
open TUnit.Core
open TUnit.Assertions
open TUnit.Assertions.FSharp.Operations
open TUnit.Assertions.Extensions

type Tests() =

[<ClassDataSource(typeof<WebApplicationFactory>, Shared = SharedType.PerTestSession)>]
member val public WebApplicationFactory: WebApplicationFactory = Unchecked.defaultof<WebApplicationFactory> with get, set

[<Test>]
member this.Test() =
async {
let client = this.WebApplicationFactory.CreateClient()
let! response = client.GetAsync("/ping") |> Async.AwaitTask
let! stringContent = response.Content.ReadAsStringAsync() |> Async.AwaitTask
do! check (Assert.That<string>(stringContent).IsEqualTo("Hello, World!"))
}

[<Test>]
member this.GetWeatherForecast() =
async {
let client = this.WebApplicationFactory.CreateClient()
let! response = client.GetAsync("/weatherforecast") |> Async.AwaitTask
let! stringContent = response.Content.ReadAsStringAsync() |> Async.AwaitTask
do! check (Assert.That<string>(stringContent).IsNotNullOrEmpty())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace TestProject

open System.Threading.Tasks
open Microsoft.AspNetCore.Mvc.Testing
open TUnit.Core.Interfaces

type WebApplicationFactory() =
inherit WebApplicationFactory<WebApp.Program.Program>()

interface IAsyncInitializer with
member this.InitializeAsync() : Task =
let _ = this.Server
Task.CompletedTask


Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace WebApp.Controllers

open System
open System.Collections.Generic
open System.Linq
open System.Threading.Tasks
open Microsoft.AspNetCore.Mvc
open Microsoft.Extensions.Logging
open WebApp

[<ApiController>]
[<Route("[controller]")>]
type WeatherForecastController (logger : ILogger<WeatherForecastController>) =
inherit ControllerBase()

let summaries =
[|
"Freezing"
"Bracing"
"Chilly"
"Cool"
"Mild"
"Warm"
"Balmy"
"Hot"
"Sweltering"
"Scorching"
|]

[<HttpGet>]
member _.Get() =
let rng = System.Random()
[|
for index in 0..4 ->
{ Date = DateTime.Now.AddDays(float index)
TemperatureC = rng.Next(-20,55)
Summary = summaries.[rng.Next(summaries.Length)] }
|]
Loading
Loading