I have the following interface that provides me a way to work with cookies:
/// <summary>
/// Provides an interface that makes it easy to work with cookies.
/// </summary>
public interface ICookies
{
#region Properties
/// <summary>
/// Gets or sets the value of the <see cref="ICookies"/>.
/// </summary>
/// <param name="name">The name of the cookie.</param>
/// <returns>A string that represents the value in this cookie.</returns>
string this[string name] { get; set; }
#endregion
#region Methods
/// <summary>
/// Writes a new cookie.
/// </summary>
/// <param name="name">The name of the cookie.</param>
/// <param name="expiration">The <see cref="DateTime"/> when this cookie expires.</param>
/// <param name="value">The value that the cookie should have.</param>
void Create(string name, string value, DateTime expiration);
/// <summary>
/// Checks wether a cookie with a specific name does exist.
/// </summary>
/// <param name="name">The name of the cookie.</param>
/// <returns><see langword="true"/> if the cookie does exists, otherwise, <see langword="false"/>.</returns>
bool DoesExist(string name);
#endregion
}
And I have the following manager that takes the ICookie interface from above to create cookies. And that class looks like the following:
/// <summary>
/// Provides an easy way to work with cookies on the server.
/// </summary>
public static class CookieManager
{
#region Methods
/// <summary>
/// Writes a new cookie on the.
/// </summary>
/// <param name="cookies">The <see cref="ICookies" /> that is responsible for working with cookies.</param>
/// <param name="name">The name of the cookie.</param>
/// <param name="value">The value of the cookie.</param>
public static void Write(ICookies cookies, string name, string value)
{
if (!Exists(cookies, name))
{
cookies.Create(name, value, DateTime.Now.AddYears(1));
}
cookies[name] = value;
}
/// <summary>
/// Reads a cookie.
/// </summary>
/// <param name="cookies">The <see cref="ICookies" /> that is responsible for working with cookies.</param>
/// <param name="name">The name of the cookie to read.</param>
/// <returns>The value of the cookie.</returns>
/// <exception cref="KeyNotFoundException">The cookie is not existing.</exception>
public static string Read(ICookies cookies, string name)
{
return cookies[name];
}
/// <summary>
/// Check if a cookie does exists.
/// </summary>
/// <param name="cookies">The <see cref="ICookies" /> that is responsible for working with cookies.</param>
/// <param name="name">The name of the cookie.</param>
/// <returns><see langword="true" /> when the cookie does exists, otherwise <see langword="false" />.</returns>
public static bool Exists(ICookies cookies, string name)
{
return cookies.DoesExist(name);
}
#endregion
}
Now, I would like to write a Unit test that mocks the cookie interface to make sure it passes.
I would like to check the following:
When I call CookieManager.Write a cookie should be written and I should be able to read it using the CookieManager.Read function. What's the correct approach for that because I've already tried everything (working with the Verifyable, Setup, SetupGet, SetupSet).
Quite important to say is that I'm working with Moq.
Here's what I have for the moment:
I have a constant first:
protected const string CookieReturnValue = "ReturnValue";
Then I have my mock of ICookie:
protected override void Arrange()
{
cookies = new Mock<ICookies>();
cookies.Setup(c => c.Create(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DateTime>()));
cookies.SetupGet(c => c[It.IsAny<string>()]).Returns(CookieReturnValue).Verifiable();
}
Then the test is executed:
protected override void Act()
{
CookieManager.Write(cookies.Object, "MyCookie", "MyValue");
CookieManager.Read(cookies.Object, "MyCookie");
}
And at the very end, the test is verified:
cookies.Verify();
Now, this test is passing, but I'm not too sure if this is the correct way of testing since in my mock, I'm returning the constant 'CookieReturnValue'. I should be able to set it to the value entered as the second parameter in the 'cookies.Setup()' method, where the 2nd parameter holds the value of the cookie.
The main problem here is that the test is also passing if I'm not writing a cookie. I need to make sure that the test is only passing when I'm writing a cookie and then reading the same cookie again.
Can someone if this is the correct way of testing or where that I should adapt it in order to make sure it's working correctly?
You have actually three tests.
The first one tests if the CookieManager checks if a cookie exists, and when not, call Create, then set the cookie:
var cookies = new Mock<ICookies>();
// there's no cookie
cookies.Setup(c => c.DoesExist(It.IsAny<string>())).Returns(false);
CookieManager.Write(cookies.Object, "MyCookie", "MyValue");
// check if create was called with the right parameters
cookies.Verify(c => c.Create("MyCookie", "MyValue", It.IsAny<DateTime>()));
// check if the cookie was set
cookies.VerifySet(mock => mock["MyCookie"] = "MyValue");
The second one tests if the CookieManager checks if a cookie exists, and when it does, don't call Create, then set the cookie:
// there's a cookie
cookies.Setup(c => c.DoesExist(It.IsAny<string>())).Returns(true);
CookieManager.Write(cookies.Object, "MyCookie", "MyValue");
// check if create was NOT called
cookies.Verify(c => c.Create(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<DateTime>()), Times.Never);
// check if the cookie was set
cookies.VerifySet(mock => mock["MyCookie"] = "MyValue");
The third one tests if the CookieManager attempts to read the cookie:
var cookies = new Mock<ICookies>();
CookieManager.Read(cookies.Object, "MyCookie");
// check if the indexer was used with the right key
cookies.Verify(c => c["MyCookie"]);
Note: simply calling cookies.Verify() does nothing on its own. You either have to provide a delegate to Verify, like I did in my examples, or call VerifyAll to verify all SetUps.
Also, you could make these tests more strict by e.g. using Times.Once or MockBehavior.Strict.
For example, the first test could also be written as:
var cookies = new Mock<ICookies>(MockBehavior.Strict);
// there's no cookie
cookies.Setup(c => c.DoesExist("MyCookie")).Returns(false);
// so one has to be created with the right parameters
cookies.Setup(c => c.Create("MyCookie", "MyValue", It.IsAny<DateTime>()));
cookies.SetupSet(mock => mock["MyCookie"] = "MyValue");
CookieManager.Write(cookies.Object, "MyCookie", "MyValue");
cookies.VerifyAll();
Also, I don't know why the CookieManager sets the cookie value again after it just created it with cookies.Create(...).
Furthermore, there's no need to setup the mock to return the constant CookieReturnValue and then check if that constant is actually returnd my that mock. This would not test the CookieManager, but rather the mock object itself, which is pointless.
Related
We have 3 cleints namely- TestingClient, ITestingClient and ITestingClientExtension. Ideally we would like to assign a variable in our winform. In order to assign the variable we declared
TestingClient client = new TestingClient(new Uri("https://rserver.contoso.com:12800")); We get an error stating delegation handler is protected. How do we establish this connection. Thank you
TestingClient.cs begins with this:
{
/// <summary>
/// The base URI of the service.
/// </summary>
public Uri BaseUri { get; set; }
/// <summary>
/// Gets or sets json serialization settings.
/// </summary>
public JsonSerializerSettings SerializationSettings { get; private set; }
/// <summary>
/// Gets or sets json deserialization settings.
/// </summary>
public JsonSerializerSettings DeserializationSettings { get; private set; }
/// <summary>
/// Subscription credentials which uniquely identify client subscription.
/// </summary>
public ServiceClientCredentials Credentials { get; private set; }
/// <summary>
/// Initializes a new instance of the TestingClient class.
/// </summary>
/// <param name='handlers'>
/// Optional. The delegating handlers to add to the http client pipeline.
/// </param>
protected TestingClient(params DelegatingHandler[] handlers) : base(handlers)
{
this.Initialize();
}
/// <summary>
/// Initializes a new instance of the TestingClient class.
/// </summary>
/// <param name='rootHandler'>
/// Optional. The http client handler used to handle http transport.
/// </param>
/// <param name='handlers'>
/// Optional. The delegating handlers to add to the http client pipeline.
/// </param>
protected TestingClient(HttpClientHandler rootHandler,params DelegatingHandler[]handlers):base(rootHandler,handlers)
{
this.Initialize();
}```
In a nutshell, you should use one of the public constructors rather than your current attempt to use one of the protected ones. Here's a screenshot (with public constructors in yellow) from a recent client I generated for that APIs, in the same way yours was generated ("Add REST Client").
For example, your code will need to look more like
Uri u = new Uri("https://rserver.contoso.com:12800")
ServiceCredential sc = ...create a relevant credential...
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ fill it in
TestingClient client = new TestingClient(u, sc);
In my Web api project I am having a controller DocumentViewerV1Controller which has a code as:
/// <summary>
///
/// </summary>
/// <param name="documentViewerService"></param>
public DocumentViewerV1Controller(IDocumentViewerService<HtmlViewInformation> documentViewerService)
{
_documentViewerHtmlService = documentViewerService;
}
/// <summary>
///
/// </summary>
/// <param name="documentViewerService"></param>
public DocumentViewerV1Controller(IDocumentViewerService<PageImage> documentViewerService)
{
_documentViewerImageService = documentViewerService;
}/// <summary>
/// Rendering Document as Html
/// </summary>
/// <returns></returns>
[HttpGet]
[Route(WebApiConfig.RootApiUri + "/v1/viewashtml/{docid}")]
public string ViewAsHtml(string docId)
{
var documentInfo = new DocumentInfo { DocumentName = HostingEnvironment.MapPath("~/Uploads/") + docId };
var response = _documentViewerHtmlService.RenderDocument(documentInfo, DocumentRenderType.Html);
return GenerateResponse(response);
}
When I run my service, make a call and debug the constructor initialization, It doesn't goes through the initialization which makes _documentViewerHtmlService as null, eventually fails returning Null reference Exception.
Is it possible to have service Interface as IDocumentViewerService?
Yes, but you'll need to remove one of the constructors or tell it which one to use.
container.RegisterType<IViewerInformation, HtmlViewerInformation>();
container.RegisterType<IDocumentViewerService<IViewerInformation>, DocumentViewerServce<IViewerInformation>>();
You may / may not also need to initialize some of the constructors which you can do by
container.RegisterType<IDocumentViewerService<IViewerInformation>, DocumentViewerServce<IViewerInformation>>(
new InjectionConstructor(...));
Short:
For each and every request a new OWIN context is created, I would like to be able to prevent this for certain resource types or paths (images, css, js).
Full:
In our application start-up we register a dbcontext creation delegate so that the dbcontext will be created just once per request.
public virtual void Configuration(IAppBuilder app)
{
app.CreatePerOwinContext(Factory.DbContextCreateDelegate);
}
If a client makes a request for the style sheet, an OWIN context will be created an thus a new dbcontext will also be created. I would like to be able to either not create the OwinContext at all, or at least to be able to prevent some of it's "on create" callbacks to be executed for certain request types/paths.
Alternatively, as I can see why the approach of (partially) "disabling" OWIN would lead to problems, I would like to hear what the best practice would be? How can I serve a static file without creating a database context for each request? (small remark here is that our static files are embedded resources served using a virtual path provider... The problem also occurs for "normal" static files.)
Background: Yesterday I started noticing that every now and then some parts of our application did not load. Sometimes it was single image, sometimes the entire CSS file. After some investigation I saw that some requests were throwing http 500 errors, the exception thrown was often things like a SQL connection time out (but also other exceptions).
While we are of course trying to fix those exceptions. I do believe it to be complete nonsense for our application to set up a database connection when a client makes a request for a single image... That's about 10 database connections for a single page request???
Seems to me like such an obvious problem but I have been Googling all of yesterday and found nothing close to a solution or work around. What am I missing stack?
EDIT: I just tried an approach where I did not actually create the dbcontext but a stub instead. In hindsight this obviously is not the solution to this problem as the OwinContext tries to continue it's process and will critically fail when it tries to get the user from the database using that stub dbcontext. The dbcontext is not the problem, I need to completely bypass Owin... I think...
Microsoft.Owin.StaticFiles to the rescue!
I would still like to know why this is not enabled by default in the MVC OWIN template application. But for most cases it is just a matter of a single line of code to enable static files in OWIN.
BASIC SCENARIO
Setting up Owin to treat a folder and its contents as static files:
public virtual void Configuration(IAppBuilder app)
{
app.UseStaticFiles("/PathToYourStaticFilesFolder");
}
SCENARIO WITH EMBEDDED RESOURCES
Unfortunately for me we are serving most of our static content as embedded resources using an implementation of a VirtualPathProvider. Luckily this is also relatively easy to implement, though it does require writing a wrapper around your VirtualPathProvider to implement the required IFileSystem and IFileInfo interfaces that OWIN requires.
Relevant parts of code from my final solution, not posting the entire VirtualPathProvider as there are plenty of examples for that online.
The wrapper around the VirtualPathProvider:
/// <summary>
/// Represents a virtual file system.
/// A wrapper around <see cref="MyCustomVirtualPathProvider"/> implementing
/// IFileSystem for use in Owin StaticFiles.
/// </summary>
public class VirtualFileSystem : IFileSystem
{
/// <summary>
/// Locate the path in the virtual path provider
/// </summary>
/// <param name="subpath">The path that identifies the file</param>
/// <param name="fileInfo">The discovered file if any</param>
/// <returns>
/// True if a file was located at the given path
/// </returns>
public bool TryGetFileInfo(string subpath, out IFileInfo fileInfo)
{
MyCustomVirtualPathProvider virtualPathProvider =
(MyCustomVirtualPathProvider) HostingEnvironment.VirtualPathProvider;
if (!virtualPathProvider.FileExists(subpath))
{
fileInfo = null;
return false;
}
try
{
EmbeddedResourceVirtualFile virtualFile =
(EmbeddedResourceVirtualFile) virtualPathProvider.GetFile(subpath);
fileInfo = new EmbeddedResourceFileInfo(virtualFile);
return true;
}
catch (InvalidCastException)
{
fileInfo = null;
return false;
}
}
/// <summary>
/// Not used in our implementation
/// </summary>
/// <param name="subpath"></param>
/// <param name="contents"></param>
/// <returns></returns>
public bool TryGetDirectoryContents(string subpath, out IEnumerable<IFileInfo> contents)
{
throw new NotImplementedException();
}
}
The wrapper around the embedded resource:
/// <summary>
/// Represents the file info of an embedded resource
/// </summary>
public class EmbeddedResourceFileInfo : IFileInfo
{
/// <summary>
/// Return file contents as readonly stream. Caller should dispose stream when complete.
/// </summary>
/// <returns>
/// The file stream
/// </returns>
public Stream CreateReadStream()
{
return virtualFile.Open();
}
/// <summary>
/// The length of the file in bytes, or -1 for a directory info
/// </summary>
public long Length => virtualFile.Length;
/// <summary>
/// The name of the file
/// </summary>
public string Name => virtualFile.Name;
/// <summary>
/// When the file was last modified
/// </summary>
public DateTime LastModified => virtualFile.LastModified;
/// <summary>
/// Returns null as these are virtual files
/// </summary>
public string PhysicalPath => null;
/// <summary>
/// True for the case TryGetDirectoryContents has enumerated a sub-directory
/// </summary>
public bool IsDirectory => virtualFile.IsDirectory;
private readonly EmbeddedResourceVirtualFile virtualFile;
/// <summary>
/// Construct using a <see cref="EmbeddedResourceVirtualFile"/>
/// </summary>
/// <param name="virtualFile"></param>
public EmbeddedResourceFileInfo(EmbeddedResourceVirtualFile virtualFile)
{
this.virtualFile = virtualFile;
}
}
And lastly, setting up Owin to use our virtual file system:
public virtual void Configuration(IAppBuilder app)
{
var staticFilesOptions = new StaticFileOptions
{
FileSystem = new VirtualFileSystem()
};
app.UseStaticFiles(staticFilesOptions);
}
Assuming that the REST and Data access interactions will be somewhat standard, I want to be able to create an abstract type to represent entity objects to pass back and forth from REST client (e.g. JavaScript in a browser) to the persistence layer without writing/registering/routing a bunch of different WebAPI controllers.
How can one create one controller base type implementation to manage persistence of several different entity type REST interactions? I.e. how can I make this work with WebAPI?
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Web;
using System.Web.Http;
namespace DynamicEntityApiControllers
{
/// <summary>
///
/// </summary>
public class EntityController<T> : ApiController
where T : EntityObject
{
private readonly IDaoProvider daoProvider;
/// <summary>
/// Initializes a new instance of the <see cref="EntityController{T}"/> class.
/// </summary>
/// <param name="daoProvider">The DAO provider.</param>
protected EntityController(IDaoProvider daoProvider)
{
this.daoProvider = daoProvider;
}
/// <summary>
/// Gets the name of the collection.
/// </summary>
/// <value>
/// The name of the collection.
/// </value>
protected string CollectionName
{
get
{
return (string)this.RequestContext.RouteData.Values["controller"];
}
}
/// <summary>
/// Gets the specified entity by key from the collection.
/// </summary>
/// <param name="key">The key.</param>
/// <returns></returns>
public T Get(string key)
{
return this.daoProvider.Output<T>(this.CollectionName, key).Data;
}
/// <summary>
/// Creates or updates the specified entity by key in the collection.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="updating">The updating.</param>
/// <returns></returns>
public T Put(string key, [FromBody] T updating)
{
var daoObject = DaoEntity.Create(this.CollectionName, key, updating);
return this.daoProvider.Input<T>(daoObject).Data;
}
/// <summary>
/// Creates or Updates the collection specified entirely.
/// </summary>
/// <param name="replacingCollection">The replacing collection.</param>
/// <returns></returns>
public IEnumerable<T> Put([FromBody] IEnumerable<T> replacingCollection)
{
return this.daoProvider.Input<T>(replacingCollection
.Select(o => DaoEntity.Create(this.CollectionName, o)));
}
/// <summary>
/// creates a new entity in the specified collection.
/// </summary>
/// <param name="creating">The creating.</param>
/// <returns></returns>
public T Post([FromBody] T creating)
{
var daoEntity = DaoEntity.Create(this.CollectionName, creating);
return this.daoProvider.Input(daoEntity).Data;
}
/// <summary>
/// Deletes the specified entity by key from the collection.
/// </summary>
/// <param name="key">The key.</param>
public void Delete(string key)
{
this.daoProvider.Delete(this.CollectionName, key);
}
}
}
the JavaScript client must look/act something like this:
$.ajax({url: '/Book', method: 'POST', data: {title: 'This StackOverflow Post', pageCount: '124' })
.done(function(data) {
$.get('/Book/'+data.Key).done(function(data) {
// this will return the book you just created
console.dir(data);
})
})
$.ajax({url: '/Book', method: 'POST', data: {title: 'Some other StackOverflow Post', pageCount: '236' })
.done(function(data) {
$.get('/Magazine/'+data.Key).done(function(data) {
// this will return 404 status code because you're asking for the book's key
// in the Magazines collection
console.dir(data);
})
})
the sample solution has a bunch TODO here (like actually do right with ETag header, if-match, etc...) but I had to do about 4 queries across StackOverflow to find these bits.
Prerequisites:
Autofac (IoC) integration with WebAPI
WebAPI Controller Location / DependencyResolver (these are not the same things)
C# Generics
Reflection IL Emitting
very minimal REST understanding and what an ETag is.
GIT source folder
briefly, here is the logic:
create a base type (entityobject)
identify all those entities at IoC Registration time via reflection (Implementer is responsible for specifying which assemblies to scan)
create concrete implementations of abstract class EntityController via IL Emitting
Tell the SupportsDynamicControllerTypeResolver about these dynamic types
IDaoProvider implementation is the "persistence" layer. implement your persistence logic here.. in this sample, an in memory dictionary is used.
And what happens when a request is made:
- RouteTable is interrogated (finds {controller}/{key} route which is an HttpRoute
- Controller name matches EntityObject implementer name minus Entity. I.e. BookEntity => BookController
- SupportsDynamicControllerTypeResolver is required here to get dynamic assembly types as valid candidates for WebApi to try to activate.
- HTTP Put/Get/Post/Delete methods find the correct method
- persistence layer does the rest
I've run into a bit of an issue trying to unit test an MVC site I have: I require a lot of the ASP.NET environment to be running (generation of httpcontexts, sessions, cookies, memberships, etc.) to fully test everything.
Even to test some of the less front end stuff needs memberships in order to properly work, and it's been finicky to get this all spoofed by hand.
Is there a way to spin up an application pool inside of NUnit tests? That seems like the easiest way.
If written properly, you shouldn't need to have a real context, real session, cookies, etc. The MVC framework by default provides a HttpContext that can be mocked/stubbed. I'd recommend using a mocking framework like Moq or Rhino Mocks and creating a MockHttpContext class that creates a mock context with all of the properties that you need to test against set up. Here's a mock HttpContext that uses Moq
/// <summary>
/// Mocks an entire HttpContext for use in unit tests
/// </summary>
public class MockHttpContextBase
{
/// <summary>
/// Initializes a new instance of the <see cref="MockHttpContextBase"/> class.
/// </summary>
public MockHttpContextBase() : this(new Mock<Controller>().Object, "~/")
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MockHttpContextBase"/> class.
/// </summary>
/// <param name="controller">The controller.</param>
public MockHttpContextBase(Controller controller) : this(controller, "~/")
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MockHttpContextBase"/> class.
/// </summary>
/// <param name="url">The URL.</param>
public MockHttpContextBase(string url) : this(new Mock<Controller>().Object, url)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="MockHttpContextBase"/> class.
/// </summary>
/// <param name="controller">The controller.</param>
/// <param name="url">The URL.</param>
public MockHttpContextBase(ControllerBase controller, string url)
{
HttpContext = new Mock<HttpContextBase>();
Request = new Mock<HttpRequestBase>();
Response = new Mock<HttpResponseBase>();
Output = new StringBuilder();
HttpContext.Setup(x => x.Request).Returns(Request.Object);
HttpContext.Setup(x => x.Response).Returns(Response.Object);
HttpContext.Setup(x => x.Session).Returns(new FakeSessionState());
Request.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
Request.Setup(x => x.QueryString).Returns(new NameValueCollection());
Request.Setup(x => x.Form).Returns(new NameValueCollection());
Request.Setup(x => x.ApplicationPath).Returns("~/");
Request.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(url);
Request.Setup(x => x.PathInfo).Returns(string.Empty);
Response.Setup(x => x.Cookies).Returns(new HttpCookieCollection());
Response.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns((string path) => path);
Response.Setup(x => x.Write(It.IsAny<string>())).Callback<string>(s => Output.Append(s));
var requestContext = new RequestContext(HttpContext.Object, new RouteData());
controller.ControllerContext = new ControllerContext(requestContext, controller);
}
/// <summary>
/// Gets the HTTP context.
/// </summary>
/// <value>The HTTP context.</value>
public Mock<HttpContextBase> HttpContext { get; private set; }
/// <summary>
/// Gets the request.
/// </summary>
/// <value>The request.</value>
public Mock<HttpRequestBase> Request { get; private set; }
/// <summary>
/// Gets the response.
/// </summary>
/// <value>The response.</value>
public Mock<HttpResponseBase> Response { get; private set; }
/// <summary>
/// Gets the output.
/// </summary>
/// <value>The output.</value>
public StringBuilder Output { get; private set; }
}
/// <summary>
/// Provides Fake Session for use in unit tests
/// </summary>
public class FakeSessionState : HttpSessionStateBase
{
/// <summary>
/// backing field for the items in session
/// </summary>
private readonly Dictionary<string, object> _items = new Dictionary<string, object>();
/// <summary>
/// Gets or sets the <see cref="System.Object"/> with the specified name.
/// </summary>
/// <param name="name">the key</param>
/// <returns>the value in session</returns>
public override object this[string name]
{
get
{
return _items.ContainsKey(name) ? _items[name] : null;
}
set
{
_items[name] = value;
}
}
}
There's a few things that you could add further like a HTTP Headers collection, but hopefully it demonstrates what you can do.
To use
var controllerToTest = new HomeController();
var context = new MockHttpContextBase(controllerToTest);
// do stuff that you want to test e.g. something goes into session
Assert.IsTrue(context.HttpContext.Session.Count > 0);
With regards to Membership providers or other providers, you've hit on something that can be hard to test. I would abstract the usage of the provider behind an interface such that you can provide a fake for the interface when testing a component that relies on it. You'll still have trouble unit testing the concrete implementation of the interface that uses the provider however but your mileage may vary as to how far you want/have to go with regards to unit testing and code coverage.
I'm not aware of a way to do that since your code isn't in that process and requires a host that isn't in aspnet either. (I've been wrong before though haha)
Theres an older HttpSimulator from Phil Haack, have you given that a whirl?
http://haacked.com/archive/2007/06/19/unit-tests-web-code-without-a-web-server-using-httpsimulator.aspx
You need to build wrapper interfaces for those services. The original MVC2 and MV3 starter project templates did this by default, but for some reason they dropped that in the latest versions.
You can try to find samples of the original AccountController code to give you a starting place. They used IMembershipService and IFormsAuthenticationService
It's relatively straightforward to mock session, context, etc..
Take a look at the MVCContrib project (http://mvccontrib.codeplex.com/) as they have a helper for creating controllers that have all the various contextual objects populated (like HttpContext).