我通常使用Machine.Fakes在我的MSpec中模拟IDocumentSession,这是RavenDB的人不喜欢的。如何将EmbeddableDocumentStore与Machine.Fakes一起使用?
答案 0 :(得分:2)
要点:https://gist.github.com/JasonMore/5345697
将RavenDB InMemory挂钩到Machine.Fakes
public class RavenInMemorySlowRunner
{
public class NoStaleQueriesAllowed : IDocumentQueryListener
{
public void BeforeQueryExecuted(IDocumentQueryCustomization queryCustomization)
{
queryCustomization.WaitForNonStaleResults();
}
}
public class AllDocumentsById : AbstractIndexCreationTask
{
public override IndexDefinition CreateIndexDefinition()
{
return new IndexDefinition
{
Name = "AllDocumentsById",
Map = "from doc in docs let DocId = doc[\"@metadata\"][\"@id\"] select new {DocId};"
};
}
}
public static EmbeddableDocumentStore Store { get; set; }
public static IDocumentSession Session { get; set; }
OnEstablish context = fakeAccessor =>
{
fakeAccessor.Configure(x => x.For<IDocumentSession>().Use(() =>
{
if (Store == null)
{
Store = new EmbeddableDocumentStore { RunInMemory = true };
Store.RegisterListener(new NoStaleQueriesAllowed());
Store.Initialize();
// RegisterServicesWithNinject is in the project where the indexes live
IndexCreation.CreateIndexes(typeof(RegisterServicesWithNinject).Assembly, Store);
IndexCreation.CreateIndexes(typeof(RavenInMemorySlowRunner).Assembly, Store);
}
if (Session == null)
{
Session = Store.OpenSession();
}
return Session;
}));
};
OnCleanup subject = subject =>
{
Session.Advanced.DocumentStore.DatabaseCommands.DeleteByIndex("AllDocumentsById", new IndexQuery());
Session.SaveChanges();
Session.Dispose();
};
}
测试
public class CurrentSiteModelServiceSpecs : WithSubject<CurrentSiteModelService>
{
Establish that = () =>
{
// use the raven in memory runner since
// we are using lots of raven magic in this service
With(new RavenInMemorySlowRunner());
};
}
/// <summary>
/// Determine Site Model for Dev
/// </summary>
public class When_Determining_SiteModel_for_dev : CurrentSiteModelServiceSpecs
{
public static SiteViewModel _siteViewModelResult;
public static IHttpCookie _cookie;
Because of = () =>
_siteViewModelResult = Subject.DetermineSiteModelForDevEnvironment();
}
public class And_Cookie_not_set : When_Determining_SiteModel_for_dev
{
It returns_null = () =>
_siteViewModelResult.ShouldBeNull();
}
public class And_Cookie_set : When_Determining_SiteModel_for_dev
{
Establish that = () =>
{
_cookie = An<IHttpCookie>();
_cookie.Value = "site/123";
The<ICookieService>()
.WhenToldTo(x => x.GetCookie(".CMS3DevSite"))
.Return(_cookie);
var site1 = new SiteModel{ Id = "site/123", HostName = "foo" };
var site2 = new SiteModel{ Id = "site/456", HostName = "bar" };
The<IDocumentSession>().Store(site1);
The<IDocumentSession>().Store(site2);
The<IDocumentSession>().SaveChanges();
};
It loads_site = () =>
_siteViewModelResult.HostName.ShouldEqual("foo");
}
public class And_Cookie_set_but_site_does_not_exist : When_Determining_SiteModel_for_dev
{
Establish that = () =>
{
_cookie = An<IHttpCookie>();
_cookie.Value = "site/123";
The<ICookieService>()
.WhenToldTo(x => x.GetCookie(".CMS3DevSite"))
.Return(_cookie);
};
It returns_null = () =>
_siteViewModelResult.ShouldBeNull();
}
我正在测试的服务
public interface ICurrentSiteModelService { RedirectToResult SetSiteModel(string path,Uri url); }
public class CurrentSiteModelService : ICurrentSiteModelService
{
readonly IDocumentSession _documentSession;
readonly ICookieService _cookieService;
public CurrentSiteModelService(
IDocumentSession documentSession,
ICookieService cookieService)
{
_documentSession = documentSession;
_cookieService = cookieService;
}
// cruft removed here
// load site in dev mode based on cookie.
internal SiteViewModel DetermineSiteModelForDevEnvironment()
{
var cookie = _cookieService.GetCookie(".CMS3DevSite");
if (cookie != null && !String.IsNullOrEmpty(cookie.Value))
{
SiteViewModel site = _documentSession.
Query<SiteViewModel, SiteViewIndex>()
.Where(s => s.Id == cookie.Value)
.AsProjection<SiteViewModel>()
.FirstOrDefault();
if (site != null)
{
return site;
}
}
return null;
}
}