Unit testing 使用RavenDB EmbeddedableDocumentStore的Machine.Fakes单元测试

Unit testing 使用RavenDB EmbeddedableDocumentStore的Machine.Fakes单元测试,unit-testing,ravendb,mspec,machine.fakes,Unit Testing,Ravendb,Mspec,Machine.fakes,我通常用Machine.Fakes在我的MSpec中模拟IDocumentSession,RavenDB的家伙不喜欢它。如何将EmbeddedBleDocumentStore与Machine.Fakes一起使用?要点: 将内存中的RavenDB挂接到机器上。伪造 public class RavenInMemorySlowRunner { public class NoStaleQueriesAllowed : IDocumentQueryListener { p

我通常用Machine.Fakes在我的MSpec中模拟IDocumentSession,RavenDB的家伙不喜欢它。如何将EmbeddedBleDocumentStore与Machine.Fakes一起使用?

要点:

将内存中的RavenDB挂接到机器上。伪造

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();
    };
}
公共类RavenInMemorySlowRunner
{
允许的公共类NostaleQueries:IDocumentQueryListener
{
执行查询之前的公共无效(IDocumentQueryCustomization queryCustomization)
{
queryCustomization.WaitForNonSaleResults();
}
}
公共类AllDocumentsById:AbstractIndexCreationTask
{
公共重写IndexDefinition CreateIndexDefinition()
{
返回新的索引定义
{
Name=“AllDocumentsById”,
Map=“从文档中的文档让DocId=doc[\“@metadata\”][\“@id\”]选择新的{DocId};”
};
}
}
公共静态EmbeddedBleDocumentStore存储{get;set;}
公共静态IDocumentSession会话{get;set;}
OnEstablish context=fakeAccessor=>
{
配置(x=>x.For()。使用(()=>
{
if(Store==null)
{
Store=new EmbeddedBleDocumentStore{RunInMemory=true};
RegisterListener(new NoStaleQueriesAllowed());
Store.Initialize();
//RegisterServicesWithNinject位于索引所在的项目中
CreateIndexes(typeof(RegisterServicesWithNinject).Assembly,Store);
CreateIndexes(typeof(RavenInMemorySlowRunner).Assembly,Store);
}
if(会话==null)
{
Session=Store.OpenSession();
}
返回会议;
}));
};
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();
}
公共类CurrentSiteModelServiceSpecs:WithSubject
{
确定=()=>
{
//使用raven in memory runner,因为
//我们在这项服务中使用了很多乌鸦魔法
使用(新RavenInMemorySlowRunner());
};
}
/// 
///确定开发人员的站点模型
/// 
确定\u dev的\u SiteModel\u时的公共类:CurrentSiteModelServiceSpecs
{
公共静态SiteViewModel\u siteViewModelResult;
公共静态IHttpCookie_cookie;
因为=()=>
_siteViewModelResult=Subject.determinesItemModelForDevenEnvironment();
}
public类和\u Cookie \u not \u set:确定\u dev的\u SiteModel\u时
{
它返回_null=()=>
_siteViewModelResult.ShouldBeNull();
}
公共类和\u Cookie\u集:当\u确定\u dev的\u SiteModel\u时
{
确定=()=>
{
_cookie=An();
_cookie.Value=“site/123”;
()
.WhenToldTo(x=>x.GetCookie(“.CMS3DevSite”))
.返回(_cookie);
var site1=newsitemodel{Id=“site/123”,HostName=“foo”};
var site2=newsitemodel{Id=“site/456”,HostName=“bar”};
存储库(site1);
存储库(site2);
SaveChanges()文件;
};
它加载_site=()=>
_siteViewModelResult.HostName.ShouldEqual(“foo”);
}
公共类和Cookie集合,但站点不存在:当为开发者确定站点模型时
{
确定=()=>
{
_cookie=An();
_cookie.Value=“site/123”;
()
.WhenToldTo(x=>x.GetCookie(“.CMS3DevSite”))
.返回(_cookie);
};
它返回_null=()=>
_siteViewModelResult.ShouldBeNull();
}
我正在测试的服务

公共接口ICurrentSiteModelService { RedirectResult SetItemModel(字符串路径、Uri url); }

公共类CurrentSiteModelService:ICurrentSiteModelService
{
只读IDocumentSession\u documentSession;
只读ICookieService\u cookieService;
公共站点模型服务(
IDocumentSession documentSession,
ICookieService cookieService)
{
_documentSession=documentSession;
_cookieService=cookieService;
}
//积垢从这里移走了
//基于cookie以开发模式加载站点。
内部SiteViewModel DeterminesItemModelForDevenEnvironment()
{
var cookie=_cookieService.GetCookie(“.CMS3DevSite”);
if(cookie!=null&!String.IsNullOrEmpty(cookie.Value))
{
SiteViewModel站点=\u documentSession。
查询()
.Where(s=>s.Id==cookie.Value)
.AsProjection()
.FirstOrDefault();
如果(站点!=null)
{
返回站点;
}
}
返回null;
}
}

你好,杰森。整洁的东西,但请记住StackOverflow是关于提问的。我有很多很酷的代码与其他人分享,但还有更合适的地方。你可以考虑一个博客文章,一个关于Github的项目,或者为这个项目做贡献。我正在尝试做一个社区维基。如何设置?从“底线-在任何Stack Exchange站点上毫不犹豫地提问和回答您自己的问题。”???对于wiki,我认为您只需单击问题附近的链接即可。我不确定你是否可以在答案发布后再做。我想如果你把你的问题编辑成一个问题的形式,那就可以了。谢谢你的链接。:)
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;
    }
}