public async Task StartAsync_ProperlyCanceled()
        {
            MockRunner   runnerMock   = new MockRunner(t => Task.Delay(int.MaxValue, t));
            MockLifetime lifetimeMock = new MockLifetime();
            ILogger <OmexHostedService> loggerMock    = new NullLogger <OmexHostedService>();
            OmexHostedService           hostedService = new OmexHostedService(runnerMock, lifetimeMock, loggerMock);

            Assert.IsFalse(runnerMock.IsStarted, "RunServiceAsync should not be called after constructor");

            await hostedService.StartAsync(CancellationToken.None);

            Assert.IsFalse(runnerMock.IsStarted, "RunServiceAsync should not be called after StartAsync");

            lifetimeMock.ApplicationStartedSource.Cancel();
            Assert.IsTrue(runnerMock.IsStarted, "RunServiceAsync should not be called after StartAsync");

            Task task = runnerMock.Task !;

            Assert.IsFalse(task.IsCanceled, "Task should not be canceled");
            Assert.IsFalse(runnerMock.Token.IsCancellationRequested, "CancelationToken should not be canceled");

            lifetimeMock.ApplicationStoppingSource.Cancel();
            Assert.IsTrue(runnerMock.Token.IsCancellationRequested, "Task should be canceled");
            Assert.IsTrue(task.IsCanceled, "CancelationToken should be canceled");
        }
        public async Task StartAsync_HandlesExceptions()
        {
            MockRunner   runnerMock   = new MockRunner(t => Task.Run(() => throw new Exception("Totaly valid exeption")));
            MockLifetime lifetimeMock = new MockLifetime();
            ILogger <OmexHostedService> loggerMock = new NullLogger <OmexHostedService>();

            OmexHostedService hostedService = new OmexHostedService(runnerMock, lifetimeMock, loggerMock);

            Assert.IsFalse(runnerMock.IsStarted, "RunServiceAsync should not be called after constructor");

            await hostedService.StartAsync(CancellationToken.None);

            Assert.IsFalse(runnerMock.IsStarted, "RunServiceAsync should not be called after StartAsync");

            lifetimeMock.ApplicationStartedSource.Cancel();
            Assert.IsTrue(runnerMock.IsStarted, "RunServiceAsync should be called after StartAsync");
            Assert.IsFalse(runnerMock.Token.IsCancellationRequested, "CancelationToken should not be canceled");

            await lifetimeMock.CompletionTask;

            Assert.IsTrue(runnerMock.Task !.IsFaulted, "Task should be faulted");

            lifetimeMock.ApplicationStoppingSource.Cancel();
            Assert.IsTrue(runnerMock.Token.IsCancellationRequested, "Task should be canceled");
        }
        public async Task StartAsync_HandlesExceptions()
        {
            MockRunner runnerMock = new MockRunner(t => Task.Run(async() =>
            {
                await Task.Delay(5).ConfigureAwait(false);
                throw new ArithmeticException("Totaly valid exeption");
            }));
            ILogger <OmexHostedService> loggerMock = new NullLogger <OmexHostedService>();

            OmexHostedService hostedService = new OmexHostedService(runnerMock, loggerMock);

            Assert.IsFalse(runnerMock.IsStarted, "RunServiceAsync should not be called after constructor");

            await hostedService.StartAsync(CancellationToken.None).ConfigureAwait(false);

            Assert.IsTrue(runnerMock.IsStarted, "RunServiceAsync should be called after StartAsync");
            Assert.IsFalse(runnerMock.Token.IsCancellationRequested, "CancelationToken should not be canceled");

            await hostedService.StopAsync(CancellationToken.None).ConfigureAwait(false);

            Assert.IsTrue(runnerMock.Task !.IsFaulted, "Task should be faulted");
            Assert.IsTrue(runnerMock.Token.IsCancellationRequested, "Task should be canceled");
        }