To resolve this issue I defined an interface
public interface ITaskScheduler
{
    void QueueBackgroundWorkItem(Action<CancellationToken> workItem);
}
In production code I inject implementation
public class AspNetTaskScheduler : ITaskScheduler
{
    public void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
    {            
        HostingEnvironment.QueueBackgroundWorkItem(workItem);
    }
}
In test code I inject implementation
public class TaskScheduler : ITaskScheduler
{
    public void QueueBackgroundWorkItem(Action<CancellationToken> workItem)
    {
        workItem.Invoke(new CancellationToken());
    }
}
I think this is an OK solution since unit tests work and my classes that queue background tasks are decoupled from HostingEnvironment.