Unit Testing with Fluent nHibernate - Delete Data for Each Test Possibilities - c#

I have set up some In Memory SQLite Unit Tests for my Fluent NHibernate Database, which looks like this. It works fine. (Using NUnit)
namespace Testing.Database {
/// <summary>
/// Represents a memory only database that does not persist beyond the immediate
/// testing usage, using <see cref="System.Data.SQLite"/>.
/// </summary>
public abstract class InMemoryDatabase : IDisposable {
/// <summary>
/// The configuration of the memorized database.
/// </summary>
private static Configuration Configuration { get; set; }
/// <summary>
/// The singleton session factory.
/// </summary>
protected static ISessionFactory SessionFactory { get; set; }
/// <summary>
/// The current session being used.
/// </summary>
protected ISession Session { get; set; }
protected InMemoryDatabase() {
SessionFactory = CreateSessionFactory();
Session = SessionFactory.OpenSession();
BuildSchema(Session);
}
/// <summary>
/// Construct a memory based session factory.
/// </summary>
/// <returns>
/// The session factory in an SQLite Memory Database.
/// </returns>
private static ISessionFactory CreateSessionFactory() {
return FluentNHibernate.Cfg.Fluently.Configure()
.Database(FluentNHibernate.Cfg.Db.SQLiteConfiguration
.Standard
.InMemory()
.ShowSql())
.Mappings(mappings => mappings.FluentMappings.AddFromAssemblyOf<Data.Mappings.AspectMap>())
.ExposeConfiguration(configuration => Configuration = configuration)
.BuildSessionFactory();
}
/// <summary>
/// Builds the NHibernate Schema so that it can be mapped to the SessionFactory.
/// </summary>
/// <param name="Session">
/// The <see cref="NHibernate.ISession"/> to build a schema into.
/// </param>
private static void BuildSchema(ISession Session) {
var export = new NHibernate.Tool.hbm2ddl.SchemaExport(Configuration);
export.Execute(true, true, false, Session.Connection, null);
}
/// <summary>
/// Dispose of the session and released resources.
/// </summary>
public void Dispose() {
Session.Dispose();
}
}
}
So now, in order to use it, I just inherit InMemoryDatabase and add my Test methods, like this.
[TestFixture]
public class PersistenceTests : InMemoryDatabase {
[Test]
public void Save_Member() {
var member = // ...;
Session.Save(member); // not really how it looks, but you get the idea...
}
}
My problem isn't that this doesn't work. It does. But if I have two tests in the same class that test similar data, for instance ...
Username_Is_Unique() and then Email_Is_Unique(). Not real tests again, but it's a good example.
[Test]
public void Username_Is_Unique(){
var user = new User {
Name = "uniqueName"
Email = "uniqueEmail"
};
// do some testing here...
}
[Test]
public void Email_Is_Unique(){
var user = new User {
Name = "uniqueName"
Email = "uniqueEmail"
};
// do some testing here...
}
I realize these are very bad tests. These are not real tests, I am just citing an example.
In both cases, I would construct a mock User or Member or what-have you and submit it to the database.
The first one works fine, but since the database is in memory (which makes sense, since I told it to be), the second one doesn't. Effectively, the Unit Tests do not reflect real-world situations, because each test stands alone. But when running them sequentially in a batch, it behaves like it should in the real world (I suppose that's partially a good thing)
What I want to do is flush the in memory database after each method. So I came up with a simple way to do this by repeating the constructor. This goes in the InMemoryDatabase class.
protected void Restart() {
SessionFactory = CreateSessionFactory();
Session = SessionFactory.OpenSession();
BuildSchema(Session);
}
So now, in each method in my inheriting class, I call Restart() before I do my testing.
I feel like this isn't the intended, or efficient way to solve my problem. Can anyone propose a better solution?
If it is of any relevance, I am using Fluent nHibernate for the persistence, and Telerik JustMock for my Mocking - but for my database stuff, I've yet to need any mocking.

You need to drop and recreate the database for every test. Every test should be independent of the other. You can do do two thing, first have your test use a setup method (Assuming NUnit here but others have the same functionality)
[SetUp]
public void Setup()
{
// Create in memory database
Memdb = new InMemoryDatabase();
}
Alternatively, you can wrap each test in a using statement for the database. For example
[Test]
public void Test()
{
using(var db = new InMemmoryDatabase())
{
Do Some Testing Here
}
}

Related

C# Ninject Web API async query in IAuthenticationFilter causes multiple operations error in entity framework

I'm using Web API 2 with Ninject and i'm getting the following error when i've got multiple parallel HTTP calls.
A second operation started on this context before a previous asynchronous operation completed. Use 'await' to ensure that any asynchronous operations have completed before calling another method on this context. Any instance members are not guaranteed to be thread safe.
I didn't get this error before, all the code that retrieves the data from the database is async so i'm thinking its a Ninject scope issue.
NinjectWebCommon
kernel.BindHttpFilter<MyAuthenticateFilter>(FilterScope.Action);
// Database context
kernel.Bind<IUnitOfWorkAsyncFactory>().To<UnitOfWorkAsyncFactory>().InRequestScope();
kernel.Bind<IUnitOfWorkAsync>().To<UnitOfWork>().InRequestScope();
kernel.Bind<IDataFactory>().To<DataFactory>().InRequestScope();
All the Application and domain handlers are also async and make use of the same DataFactory and UnitOfWorkAsyncFactory.
Seems like there's a threading issue with the IAuthenticationFilter.
The factory pattern used for the DbContext.
public class DataFactory : Disposable, IDataFactory
{
private MyContext DbContext { get; set; }
public IDataContextAsync GetDataContext()
{
return DbContext ?? (DbContext = new MyContext());
}
public void AfterDispose()
{
DbContext = null;
}
public DataFactory()
{
}
public DataFactory(MyContext context)
{
DbContext = context;
}
}
I remember some time ago having issues with filter injection in WebApi and scopes being lost.
As far as I remember using this implementation of IDependencyResolver (can not remember where I got it) made the issue go away.
using System.Web.Http.Dependencies;
using global::Ninject.Syntax;
public class DependencyResolverWebApiNinject : DependencyScopeWebApiNinject, IDependencyResolver
{
public DependencyResolverWebApiNinject(IResolutionRoot resolutionRoot)
: base(resolutionRoot)
{
}
public virtual IDependencyScope BeginScope()
{
return this;
}
}
Where DependencyScopeWebApiNinject is :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http.Dependencies;
using global::Ninject;
using global::Ninject.Infrastructure.Disposal;
using global::Ninject.Parameters;
using global::Ninject.Syntax;
public class DependencyScopeWebApiNinject : DisposableObject, IDependencyScope
{
/// <summary>
/// Initializes a new instance of the <see cref="DependencyScopeWebApiNinject"/> class.
/// </summary>
/// <param name="resolutionRoot">The resolution root.</param>
public DependencyScopeWebApiNinject(IResolutionRoot resolutionRoot)
{
this.ResolutionRoot = resolutionRoot;
}
/// <summary>
/// Gets the resolution root.
/// </summary>
/// <value>The resolution root.</value>
protected IResolutionRoot ResolutionRoot
{
get;
private set;
}
/// <summary>
/// Gets the service of the specified type.
/// </summary>
/// <param name="serviceType">The type of the service.</param>
/// <returns>The service instance or <see langword="null"/> if none is configured.</returns>
public object GetService(Type serviceType)
{
var request = this.ResolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true);
return this.ResolutionRoot.Resolve(request).SingleOrDefault();
}
/// <summary>
/// Gets the services of the specifies type.
/// </summary>
/// <param name="serviceType">The type of the service.</param>
/// <returns>All service instances or an empty enumerable if none is configured.</returns>
public IEnumerable<object> GetServices(Type serviceType)
{
return this.ResolutionRoot.GetAll(serviceType).ToList();
}
}
hope this will help

Serving static files without going through OWIN

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);
}

How to apply business rules to a WCF data service in a generic way, backed up by EF6

I have this requirement to create a REST API to manipulate a database. I decided on WCF Data Services v5.6 because i don't want to rewrite the wheel and i think that way is becoming the standard.
BUT, i need to apply business rules to the objects. All entities involved derive from a base class that has control fields like IsDeleted and so that need checking for example, against a select/GET.
My design has 4 projects:
DomainModel: Contains only the POCO entities (made by separating the Model.tt into a new project
DataAccessLayer: Contains the Context.tt that generates the EventsDomainModel context class
BusinessLayer: Contains a custom DbContext that does the validation, more on this in a moment
RestApi: The website and the services.
Currently, this is the validation i have:
public class GenericBusinessValidator<T>:DbContext where T: class, IBaseEntity
{
private DbContext _ctx;
private DbSet<T> _set;
/// <summary>
/// Standard constructor
/// </summary>
/// <param name="context">The DbContext object</param>
public GenericBusinessValidator(DbContext context)
{
_ctx = context;
_set = _ctx.Set<T>();
}
public IEnumerable<T> GetAll()
{
return _set.Where(x => x.IsActive == true);
}
}
and the code needed to make the service work (Events.svc) is the standard
public class Events : EntityFrameworkDataService<EventsDomainModel>
{
// This method is called only once to initialize service-wide policies.
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("*", EntitySetRights.All);
config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
}
}
Now, what i am trying to achieve is to REPLACE the EventsDomainModel class wich is the vanilla DbContext -derived class from the second piece of code with the first, that does the validation but i dont know how;
The way i understand, my validator deals with a specific DbSet inside a given DbContext; the code from the WCF service needs a specific dbContext.
So, how can i validate all DbSets without particularizing my class, ie, avoid making
public class GenericBusinessValidator<T>:DbContext where T: class, IBaseEntity
{
private DbContext _ctx;
private DbSet<T> _set;
/// <summary>
/// Standard constructor
/// </summary>
/// <param name="context">The DbContext object</param>
public GenericBusinessValidator(DbContext context)
{
_ctx = context;
_set = _ctx.Set<T>();
}
private DbSet<Venue> Venues;
private DbSet<EventCategory> Categories;
...
...
...
BASICALLY, what i'm trying to accomplish is
make sure that a call like
http://localhost/Events.svc/EventCategories?$format=application/json
returns me all EventCategories that have isActive=true (applied generically) WITHOUT resorting to ServiceOperations and thus avoiding defeating the purpose of using REST
As it turns out, what i needed were QueryInterceptors and ChangeInterceptors
https://msdn.microsoft.com/en-us/library/dd744842(v=vs.110).aspx

Nunit Testing MVC Site

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).

Best Practices for modularizing Selenium RC test scripts

I am creating Selenium RC test scripts in Visual Studio (C#). I am
struggling with re-factoring the tests; all my tests are in a single
file. I would appreciate any input and/or pointers to websites, books,
etc. to learn about modularizing the tests.
I have to run the same tests on different sites (same application but
configured differently for different clients and logins) which are 95%
same. Would anybody like to provide some good examples or best
practices to do this?
Thanks!
Best practise for writing Selenium tests or any UI tests is Page Object Model which is the idea that you create an Object for each of the pages. Each of these objects abstract the page so when you write a test it doesnt really look like you have been working with Selenium.
So for a blog you would do something like this to create an object for the home page
public class Home
{
private readonly ISelenium _selenium;
/// <summary>
/// Instantiates a new Home Page object. Pass in the Selenium object created in the test SetUp().
/// When the object in instantiated it will navigate to the root
/// </summary>
/// <param name="selenium">Selenium Object created in the tests
public Home(ISelenium selenium)
{
this._selenium = selenium;
if (!selenium.GetTitle().Contains("home"))
{
selenium.Open("/");
}
}
/// <summary>
/// Navigates to Selenium Tutorials Page. Selenium object wll be passed through
/// </summary>
/// <returns>SeleniumTutorials representing the selenium_training.htm</returns>
public SeleniumTutorials ClickSelenium()
{
_selenium.Click("link=selenium");
_selenium.WaitForPageToLoad("30000");
return new SeleniumTutorials(_selenium);
}
/// <summary>
/// Click on the blog or blog year and then wait for the page to load
/// </summary>
/// <param name="year">blog or blog year
/// <returns>Object representing /blog.* pages</returns>
public Blog ClickBlogYear(string year)
{
_selenium.Click("link=" + year);
_selenium.WaitForPageToLoad("30000");
return new Blog(_selenium);
}
// Add more methods as you need them
}
then you would create a test that looks like the following
[TestFixture]
public class SiteTests
{
private ISelenium selenium;
[SetUp]
public void Setup()
{
selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://www.theautomatedtester.co.uk");
selenium.Start();
}
[TearDown]
public void Teardown()
{
selenium.Stop();
}
[Test]
public void ShouldLoadHomeThenGoToXpathTutorial()
{
Home home = new Home(selenium);
SeleniumTutorials seleniumTutorials = home.ClickSelenium();
SeleniumXPathTutorial seleniumXPathTutorial = seleniumTutorials.ClickXpathTutorial();
Assert.True(seleniumXPathTutorial.
IsInputOnScreen(SeleniumXPathTutorial.FirstInput));
Assert.True(seleniumXPathTutorial
.IsInputOnScreen(SeleniumXPathTutorial.SecondInput));
Assert.True(seleniumXPathTutorial
.IsInputOnScreen(SeleniumXPathTutorial.Total));
}
}

Categories