How can I write unit test for my background service? - c#

I'm working with the HostBuilder in .NET Core (not the WebHost !).
I have one Hosted Service running in my application that overrides the ExecuteAsync/StopAsync methods of the background Service and I want to unit test it.
Here is my HostedService:
public class DeviceToCloudMessageHostedService : BackgroundService
{
private readonly IDeviceToCloudMessageService _deviceToCloudMessageService;
private readonly AppConfig _appConfig;
public DeviceToCloudMessageHostedService(IDeviceToCloudMessageService deviceToCloudMessageService, IOptionsMonitor<AppConfig> appConfig)
{
_deviceToCloudMessageService = deviceToCloudMessageService;
_appConfig = appConfig.CurrentValue;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await _deviceToCloudMessageService.DoStuff(stoppingToken);
await Task.Delay(_appConfig.Parameter1, stoppingToken);
}
}
public override Task StopAsync(CancellationToken cancellationToken)
{
Log.Information("Task Cancelled");
_deviceToCloudMessageService.EndStuff();
return base.StopAsync(cancellationToken);
}
I already found this post: Integration Test for Hosted Service in .NET Core
But it's explained for a QueuedBackgroundService and I don't really know if I can test mine the same way.
I just want to know if my code is executed. I don't want any specific result.
Do you have any idea of how I can test it?

You should still be able to follow a similar format as the linked answer.
Mock the dependencies and inject them, invoke the methods under test and assert the expected behavior.
The following uses Moq to mock the dependencies along with ServiceCollection to do the heavy lifting of injecting the dependencies.
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
[TestMethod]
public async Task DeviceToCloudMessageHostedService_Should_DoStuff() {
//Arrange
IServiceCollection services = new ServiceCollection();
services.AddSingleton<IHostedService, DeviceToCloudMessageHostedService>();
//mock the dependencies for injection
services.AddSingleton(Mock.Of<IDeviceToCloudMessageService>(_ =>
_.DoStuff(It.IsAny<CancellationToken>()) == Task.CompletedTask
));
services.AddSingleton(Mock.Of<IOptionsMonitor<AppConfig>>(_ =>
_.CurrentValue == Mock.Of<AppConfig>(c =>
c.Parameter1 == TimeSpan.FromMilliseconds(1000)
)
));
var serviceProvider = services.BuildServiceProvider();
var hostedService = serviceProvider.GetService<IHostedService>();
//Act
await hostedService.StartAsync(CancellationToken.None);
await Task.Delay(1000);//Give some time to invoke the methods under test
await hostedService.StopAsync(CancellationToken.None);
//Assert
var deviceToCloudMessageService = serviceProvider
.GetRequiredService<IDeviceToCloudMessageService>();
//extracting mock to do verifications
var mock = Mock.Get(deviceToCloudMessageService);
//assert expected behavior
mock.Verify(_ => _.DoStuff(It.IsAny<CancellationToken>()), Times.AtLeastOnce);
mock.Verify(_ => _.EndStuff(), Times.AtLeastOnce());
}
Now, ideally this would count as testing framework code since you are basically testing that a BackgroundService behaves as expected when run, but it should demonstrate enough about how one would test such a service in isolation

Another example based on #Nkosi's excellent answer. For I was testing this StartupBackgroundService, which has a protected method ExecuteAsync:
public class StartupBackgroundService : BackgroundService
{
private readonly StartupHealthCheck _healthCheck;
public StartupBackgroundService(StartupHealthCheck healthCheck)
=> _healthCheck = healthCheck;
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
_healthCheck.StartupCompleted = true;
return Task.CompletedTask;
}
}
I can't change the scope from protected to internal and expose it with [assembly: InternalsVisibleTo("TestsAssembly")] because its derived from an Abstract class.
So I came up with this magic, it calls ExecuteAsync not StartAsync:
[Test]
public async Task Should_Setup_StartupBackgroundService()
{
//Arrange
var startUpBackServ = new StartupBackgroundService(new Base.HealthCheck.StartupHealthCheck());
// Act
startUpBackServ.StartAsync(It.IsAny<CancellationToken>()); // It calls ExecuteAsync magically!
//Assert
}
It's MAGIC!
Here's the StartupHealthCheck:
public class StartupHealthCheck : IHealthCheck
{
public bool StartupCompleted { get; set; }
public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context = null, CancellationToken cancellationToken = default)
{
if (StartupCompleted)
{
return Task.FromResult(HealthCheckResult.Healthy("The startup task has completed."));
}
return Task.FromResult(HealthCheckResult.Unhealthy("That startup task is still running."));
}
}

Related

Memory leak in Xamarin Forms app when using DI in a Task

I am creating a Xamarin Forms application, and I am using the Xamarin Profiler to show that I have a memory leak. I have tracked the memory leak down to where it is happening, but I can't understand WHY it is happening.
I have a class (we will call it MyClass for now). And that class is using a Timer to call a service once every second. That service makes a REST call to retrieve a bunch of information, and then serializes the results back into an object....
MyClass:
public class MyClass : ContentPage
{
private readonly IMyService myService;
public MyClass() : base()
{
}
protected override async void OnAppearing()
{
StartTimer();
}
private void StartTimer()
{
Task.Run(async() =>
{
while(true)
{
myService = ((App)App.Current)
.serviceProvider
.GetRequiredService<IMyService>();
//--- everytime I call myService.GetSystemStatus(), my allocated memory continues to rise
MyResponse response = await myService.GetSystemStatus();
Device.BeginInvokeOnMainThread(() =>
{
// update the UI here...
});
await Task.Delay(1000);
}
});
}
}
MyService (Singleton):
public class MyService : IMyService
{
private readonly IMyHttpClientFactory httpClientFactory;
public MyService(IMyHttpClientFactory httpClientFactory)
{
this.httpClientFactory = httpClientFactory;
}
public async Task<MyResponse> GetSystemStatus()
{
return await httpClientFactory.Create().GetAsync<MyResponse>(
"http://example.com/api/status"
);
}
}
MyHttpClientFactory (Singleton):
public class MyHttpClientFactory : IMyHttpClientFactory
{
private readonly IServiceProvider _serviceProvider;
public MyHttpClientFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public MyHttpClient Create()
{
return _serviceProvider.GetRequiredService<MyHttpClient>();
}
}
MyHttpClient:
public class MyHttpClient : IDisposable
{
private HttpClient _httpClient;
public MyHttpClient ()
{
_httpClient = new HttpClient();
_httpClient.Timeout = TimeSpan.FromSeconds(10);
}
public async Task<T> GetAsync<T>(string url) where T : new()
{
string s = await GetStringAsync(url);
return JsonConvert.DeserializeObject<T>(s);
}
public async Task<string> GetStringAsync(string url)
{
using (var response = await _httpClient.GetAsync(url))
{
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
}
}
My services are defined as follows:
public partial class App : Application
public ServiceProvider serviceProvider;
public App()
{
IServiceCollection services = new ServiceCollection();
ConfigureServices(services);
serviceProvider = services.BuildServiceProvider();
InitializeComponent();
}
private void ConfigureServices(IServiceCollection services)
{
services.AddHttpClient<MyHttpClient>("MyHttpClient", x =>
{
x.Timeout = TimeSpan.FromSeconds(5);
});
services.AddSingleton<IMyHttpClientFactory, MyHttpClientFactory>();
services.AddSingleton<IMyService, MyService>();
}
}
Best I can tell, the memory is going up because I am referencing the DI MyService inside a separate thread. But I am not sure if this is the reason or if there is something else that would be causing the leak?
Any advice would be greatly appreciated!!!
Thanks!
From what I understand from your code and your comments, it looks like you're looping by calling StartTimer() inside the Device.StartTimer() method.
According to the documentation, Device.StartTimer() is recurring and will occur every X seconds, depending of your interval parameter.
By removing the call to StartTimer() (the one between t.Dispose() and return false of MyClass.StartTimer, your code should work as expected and you will not create a new timer every x seconds
What could be the cause of the leak:
Your MyHttpClient class implements the IDisposable interface, yet the code to use an instance of this class is not leveraging the disposable nature of the object.
Even though the internal HttpClient instance is wrapped in a using statement, the MyHttpClient instance will not be disposed of as you would expect.
// from MyHttpClient class
public async Task<MyResponse> GetSystemStatus()
{
// no using statement here
return await httpClientFactory.Create().GetAsync<MyResponse>(
"http://example.com/api/status"
);
}
// should be:
public async Task<MyResponse> GetSystemStatus()
{
using (var client = await httpClientFactory.Create())
{
return await client.GetAsync<MyResponse>("http://example.com/api/status");
}
}
Another thing to try is to change the location of the resolution of the MyService instance to inside the Task since this is where it is used. This will allow the task to own the resource, and allow it to be collected when the task is complete.
private void StartTimer()
{
Device.StartTimer(TimeSpan.FromSeconds(1), () =>
{
Task t = Task.Run(async() =>
{
// resolve the service here
myService = ((App)App.Current)
.serviceProvider
.GetRequiredService<IMyService>();
MyResponse response = await myService.GetSystemStatus();
Device.BeginInvokeOnMainThread(() =>
{
// update the UI here...
});
});
t.Wait();
t.Dispose();
StartTimer();
return false;
});
}
A couple of additional observations of your code:
In your HttpClientFactory's Create() method, you are resolving an instance of your client from the DI container.
Your MyHttpClient class has a default constructor which means the resolution is not needed since there are no additional dependencies requiring DI support.
Your code could simply return a new MyHttpClient() instance from the Create() method without the need for DI.
Your MyHttpClient also implements the IMyHttpClient interface, but your factory returns the concrete type. This means you need to either remove the interface as unnecessary or change the return type to be the interface type since the interface is redundant unless it is used.
Thank you all for your answers....
I finally figured out the source of the memory leak.
The problem was that I was referencing "MyService" like this:
myService = ((App)App.Current)
.serviceProvider
.GetRequiredService<IMyService>();
The problem was that the serviceProvider object was a public property on my App. So each time I referenced the provider inside my loop, it was creating the leak.
To get around this, I added an abstract method to each of my pages that implemented MyClass to return the service correctly using DI. This has corrected my memory leak issue....
Thanks all for the help!
I don't think that your timer logic is the cause of the leak.
But in case it is useful to you, here is a clean way to do work periodically, yet if work takes a long time, avoid events "piling up".
Given await/async, no Timer is needed.
(There is an alternative solution that starts/stops a single System.Timers.Timer, but I won't go into that here.)
Replace StartTimer() declaration with the following:
/// <summary> Runs until keepRunning() returns false.
/// Delays by "msecDelay" AFTER finishing the previous loop's non-UI work. </summary>
private void StartTaskLoopWhileKeepRunning(Func<bool> keepRunning, int msecDelay = 250)
{
Task.Run(async () =>
{
while (keepRunning())
{
// Do non-UI work here.
// ... possibly slow work ...
Device.BeginInvokeOnMainThread(() =>
{
// NOTE: This work will run in parallel with the next delay.
// ... Do UI work here. ...
});
// Non-UI thread sleeps for msec.
await Task.Delay(msecDelay);
}
});
}

How can you mock an Automatonymous Activity?

I'm trying to unit test my state machine and that it transitions to the states I expect when certain events are received. To do this I'm using the InMemoryTestHarness which enables me to create my state machine and then using the bus I can publish messages to it.
For the most part this is fine. However, there are a couple of examples where it then goes off and does an activity before it transitions state like this:
During(Submitted,
When(OnFlyCoolThingRequest)
.Activity(activitySelector => activitySelector.OfType<MakeItFlyActivity>()).TransitionTo(Flying));
At this point I don't want to test the activity and as it happens it appears that it seems to actually break the test (just hangs). My test is currently setup like this:
[Test]
public async Task CoolThingSagaShouldTransitionToFlyingStateOnFlyCoolThingRequestEvent()
{
var stateMachine = new CoolStateMachine();
var harness = new InMemoryTestHarness();
var saga = harness.StateMachineSaga<CoolThingSaga, CoolStateMachine>(new CoolStateMachine());
await harness.Start();
try
{
var coolThing = GetCoolThing();
// Create a CoolThing instance.
await harness.Bus.Publish(new CoolThingCreated(coolThing.Id));
var instanceIdSubmitted = await saga.Exists(coolThing.Id, state => state.Submitted);
// Publish a FlyCoolThingRequest event for the above instance.
await harness.Bus.Publish(new FlyCoolThingRequest(coolThing.Id, DateTime.UtcNow));
var instanceIdFlying = await saga.Exists(coolThing.Id, state => state.Flying);
Assert.That(instanceIdSubmitted.Value, Is.EqualTo(instanceIdFlying.Value), $"Instance id returned between the state of '{stateMachine.Submitted.Name}' and '{stateMachine.Flying.Name}' should be the same.");
Assert.That(instanceIdFlying, Is.Not.Null, $"A CoolThingSaga instance should have been created with Id {instanceIdFlying} and a be in the state of '{stateMachine.Flying}'.");
}
finally
{
await harness.Stop();
}
}
At the moment this type of test works for testing states that don't have activities associated with them. However, the tests seem to hang when an activity is involved. So how can I mock the activity so it doesn't actually try and perform that logic?
UPDATE
Looks like it fails to create the activity due to not being able to find a parameterless constructor. My activity is akin to this:
public sealed class MakeItFlyActivity : Activity<CoolThingSaga, FlyCoolThingRequest>
{
private readonly FlyingService _flyingService;
public MakeItFlyActivity(FlyingService flyingService)
{
_flyingService = flyingService;
}
public async Task Execute(BehaviorContext<CoolThingSaga, FlyCoolThingRequest> context, Behavior<CoolThingSaga, FlyCoolThingRequest> next)
{
await flyingService.MakeItFly(context.Instance.Details.Id);
await next.Execute(context);
}
public void Accept(StateMachineVisitor visitor) => visitor.Visit(this);
public async Task Faulted<TException>(BehaviorExceptionContext<CoolThingSaga, FlyCoolThingRequest, TException> context, Behavior<CoolThingSaga, FlyCoolThingRequest> next)
where TException : Exception => await next.Faulted(context);
public void Probe(ProbeContext context) => context.CreateScope(nameof(MakeItFlyActivity));
}
My setup is as follows:
private InMemoryTestHarness fHarness;
private StateMachineSagaTestHarness<CoolThingSaga, CoolStateMachine> fSaga;
private CoolStateMachine fStateMachine;
[OneTimeSetUp]
public async Task Setup()
{
var provider = new ServiceCollection()
.AddSingleton<ILoggerFactory>(p => new TestOutputLoggerFactory(true))
.AddMassTransitInMemoryTestHarness(cfg =>
{
cfg.AddSagaStateMachine<CoolStateMachine, CoolThingSaga>().InMemoryRepository();
cfg.AddSagaStateMachineTestHarness<CoolStateMachine, CoolThingSaga>();
})
.AddSingleton(p => new FlyingService(TimeSpan.FromMinutes(15), NullLogger<FlyingService>.Instance))
.AddScoped<MakeItFlyActivity>()
.BuildServiceProvider(true);
fHarness = provider.GetRequiredService<InMemoryTestHarness>();
fSaga = fHarness.StateMachineSaga<CoolThingSaga, CoolStateMachine>(new CoolStateMachine());
fStateMachine = provider.GetRequiredService<CoolStateMachine>();
await fHarness.Start();
}
To test state machines, you should be using the container based test harness as outlined in the documentation. This will ensure that activities and their dependencies can be resolved at runtime. Your test likely hangs because the activity could not be created.
The documentation for v8 is linked, you can also refer to the v7 documentation if you're using an earlier version.

how do i make a background worker to update a datastore every 5 minutes in asp.net core

I've followed the getting started tutorial and currently have a TODO CRUD app.
https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api-mac?view=aspnetcore-2.1
I want to add a background worker that updates the todo database every 5 minutes and sets Item 1 to a random value for its Name, and isCompleted properties.
This is pretty easy in Java SpringBoot or Elixir's Phoenix...
Is there a quick and painless way in c# to do this?
The doc I found on Microsoft website was from 2012... so I assume there is a more elegant way to do this by now.
Edit: I went with DNTScheduler.Core and it was relatively painless to set up. Followed the exampleApp setup that was on github repo and here is the task i ended up using:
using System;
using System.Threading.Tasks;
using DNTScheduler.Core.Contracts;
using Microsoft.Extensions.Logging;
using myapp.Models;
namespace MyApp.Tasks
{
public class TaskOne : IScheduledTask
{
private readonly ILogger<DoBackupTask> _logger;
private readonly TodoContext _context; // autoinjects since it was added in startup.cs in configure()
public TaskOne(ILogger<DoBackupTask> logger, TodoContext context)
{
_logger = logger;
_context = context;
}
public Task RunAsync()
{
var todo = _context.TodoItems.Find(1);
if (todo == null)
{
return Task.CompletedTask;
}
string[] names = new string[] { "val1", "val2"};
Random r = new Random();
string random_name = names[r.Next(0, names.Length)];
todo.Name = random_name;
_context.TodoItems.Update(todo);
_context.SaveChanges();
_logger.LogInformation("Ran My Task\n\n ");
return Task.CompletedTask;
}
}
}
I would suggest you use Scheduler, there are some packages that can do that, but the best package that I have seen so far is DNTScheduler.Core
DNTScheduler.Core is a lightweight ASP.NET Core's background tasks runner and scheduler.
for more information, you can visit this link
I would argue that the correct answer is wrong if you want to follow the native practice.
Make use of IHostedService to perform repetitive actions.
Here’s an answer I’ve written that addresses that.
There is a saying i've read somewhere: "If its worth doing, its worth doing right. If its not worth doing right - find something that is."
So, as other colleagues already said, web application is not meant to be a container for background processes for reasons already mentioned.
Depending on your environment, you'll be much better off using:
windows services or even windows scheduler (on classic hosting) or some of the libraries for scheduling but outside of the web app. then, those scheduler, whichever it is, could just trigger API endpoint within your web app so you have business logic at one place
azure scheduler if you work with azure
pretty much anything else is looking for trouble when you don't need one.
In this sample I Insert a record to my database ( Word-Suggestion-Table in here) every hour using UnitOfWork and Repository Pattern. No error on Cannot consume scoped service *IUnitOfWork* from singleton
1- Add work class and IWork interface as below:
using System.Threading;
using System.Threading.Tasks;
namespace Map118.App.BackgroundTasks
{
public interface IWorker
{
Task DoWork(CancellationToken cancellationToken);
}
}
Work.cs :
using Map118.DataLayer.IRepositories;
using Map118.Models;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Map118.App.BackgroundTasks
{
public class Worker : IWorker
{
private readonly IServiceProvider serviceProvider;
public Worker( IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
public async Task DoWork(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
using (var scope = serviceProvider.CreateScope())
{
var _unitOfWork = scope.ServiceProvider.GetRequiredService<IUnitOfWork>();
while (!stoppingToken.IsCancellationRequested)
{
WordSuggestion wordSuggestion = new WordSuggestion()
{
word = Guid.NewGuid().ToString(),
};
await _unitOfWork.wordSuggestionRepository.Add(wordSuggestion);
await _unitOfWork.Save();
await Task.Delay(1000 * 3600);
}
}
}
}
}
}
2- Add another class as below:
using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
namespace Map118.App.BackgroundTasks
{
public class UserActivitiesCleaner : BackgroundService
{
private readonly IWorker worker;
public UserActivitiesCleaner(IWorker worker)
{
this.worker = worker;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await worker.DoWork(stoppingToken);
}
}
}
3- Add services to Startup.cs :
services.AddHostedService<UserActivitiesCleaner>();
services.AddSingleton<IWorker, Worker>();

Structure Map - Replace Interface with mock object at runtime

I am doing some integration tests for my OWIN based Web API. I am using structure map as DI container. In one of the cases, I need to mock out an API call ( can't include it as part of the test).
How would I go about doing this using Structure Map? I have done it using SimpleInjector but the code base I am working on is using Structure Map and I can't figure out how I would do this.
Solution with SimpleInjector:
Startup.cs
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
app.UseWebApi(WebApiConfig.Register(config));
// Register IOC containers
IOCConfig.RegisterServices(config);
}
ICOCConfig:
public static Container Container { get; set; }
public static void RegisterServices(HttpConfiguration config)
{
Container = new Container();
// Register
config.DependencyResolver = new SimpleInjectorWebApiDependencyResolver(Container);
}
And in my Integration test, I mock out the interface that calls the other API.
private TestServer testServer;
private Mock<IShopApiHelper> apiHelper;
[TestInitialize]
public void Intitialize()
{
testServer= TestServer.Create<Startup>();
apiHelper= new Mock<IShopApiHelper>();
}
[TestMethod]
public async Task Create_Test()
{
//Arrange
apiHelper.Setup(x => x.CreateClientAsync())
.Returns(Task.FromResult(true);
IOCConfig.Container.Options.AllowOverridingRegistrations = true;
IOCConfig.Container.Register<IShopApiHelper>(() => apiHelper.Object, Lifestyle.Transient);
//Act
var response = await testServer.HttpClient.PostAsJsonAsync("/api/clients", CreateObject());
//Assert
Assert.AreEqual(HttpStatusCode.Created, response.StatusCode);
}
I found this in the structure-map documentation but it doesn't allow me to inject a mock object in there (only types).
How I can inject a mock version of IShopApiHelper (Mock) when running my integration tests? (I am using the Moq library for mocking)
Assuming the same API structure as in the original example you can do basically the same thing as demonstrated in the linked documentation.
[TestMethod]
public async Task Create_Test() {
//Arrange
apiHelper.Setup(x => x.CreateClientAsync())
.Returns(Task.FromResult(true);
// Use the Inject method that's just syntactical
// sugar for replacing the default of one type at a time
IOCConfig.Container.Inject<IShopApiHelper>(() => apiHelper.Object);
//Act
var response = await testServer.HttpClient.PostAsJsonAsync("/api/clients", CreateObject());
//Assert
Assert.AreEqual(HttpStatusCode.Created, response.StatusCode);
}

Await Tasks in Test Setup Code in xUnit.net?

The exact situation is I'm doing E2E tests with Protractor.NET (.NET port of AngularJS's Protractor E2E framework) and I would like to make some web requests (and the API -- System.Net.Http.HttpClient -- has all Async/Task methods) to Arrange my test before I Act/Assert, only I need to do this same Arrange-ing for several tests.
I'm using xUnit.net as my test runner they use an interface (IUseFixture<T>) for per-fixture setup code. It would be nice if there was a IAsyncUseFixture<T> that had a Task SetFixtureAsync(T t); or something. I don't think such a thing exists. Additionally I don't think constructors can use await either, and constructors are the only other way to execute the same block of code per-test in xUnit.net.
What are my options? .Result? Isn't that bad practice (deadlock)?
xUnit has an IAsyncLifetime interface for async setup/teardown. The methods you need to implement are Task InitializeAsync() and Task DisposeAsync().
InitializeAsync is called immediately after the class has been created, before it is used.
DisposeAsync is called just before IDisposable.Dispose if the class also implements IDisposable.
e.g.
public class MyTestFixture : IAsyncLifetime
{
private string someState;
public async Task InitializeAsync()
{
await Task.Run(() => someState = "Hello");
}
public Task DisposeAsync()
{
return Task.CompletedTask;
}
[Fact]
public void TestFoo()
{
Assert.Equal("Hello", someState);
}
}
I would use AsyncLazy
http://blog.stephencleary.com/2012/08/asynchronous-lazy-initialization.html
In my case I want to run some integration tests against a self hosted web api.
public class BaseTest()
{
private const string baseUrl = "http://mywebsite.web:9999";
private static readonly AsyncLazy<HttpSelfHostServer> server = new AsyncLazy<HttpSelfHostServer>(async () =>
{
try
{
Log.Information("Starting web server");
var config = new HttpSelfHostConfiguration(baseUrl);
new Startup()
.Using(config)
.Add.AttributeRoutes()
.Add.DefaultRoutes()
.Remove.XmlFormatter()
.Serilog()
.Autofac()
.EnsureInitialized();
var server = new HttpSelfHostServer(config);
await server.OpenAsync();
Log.Information("Web server started: {0}", baseUrl);
return server;
}
catch (Exception e)
{
Log.Error(e, "Unable to start web server");
throw;
}
});
public BaseTest()
{
server.Start()
}
}

Categories