簡體   English   中英

如何測試 Ninject 工廠在 RequestScope 中返回相同的實例

[英]How to test a Ninject Factory returns the same instance in RequestScope

在 WebApi 應用程序中,我使用 Ninject 注入一個工廠,該工廠允許使用類創建一個根據其要求確定范圍的DbContext 我希望能夠編寫一個單元測試來驗證對同一工廠的請求范圍上下文的兩次調用返回相同的實例。

工廠界面是:

public interface IContextFactory
{
    IMyContext GetContext();
    IMyContext GetTransientContext();
}

Ninject 配置如下所示:

 Bind<IContextFactory>().ToFactory();
 Bind<IMyContext>().To<MyContext>()
     .InRequestScope()
     .NamedLikeFactoryMethod((IContextFactory f) => f.GetContext());
 Bind<IMyContext>().To<MyContext>()
     .InTransientScope()
     .NamedLikeFactoryMethod((IContextFactory f) => f.GetTransientContext());

我的單元測試如下:

[Fact]
public void RequestScopedContextAlwaysSame()
{
    // Arrange
    NinjectWebCommon.Start();
    var factory = (IContextFactory)NinjectWebCommon.Bootstrapper.Kernel.GetService(typeof(IContextFactory));

    //Act
    var context1 = factory.GetContext();
    var context2 = factory.GetContext();

    //Assert
    Assert.Same(context1, context2);
}

我希望對工廠的兩次調用都返回相同的實例,但實際上它們是兩個不同的實例。 我認為這是一個測試錯誤,因為在應用程序中,我已經能夠成功驗證在調用GetContext()方法時相同的實例被注入到不同的使用者中。

我懷疑這在單元測試中不起作用,因為沒有HttpContext並且InRequestScope()依賴於它。 有沒有辦法解決這個問題?

我懷疑這在單元測試中不起作用,因為沒有 HttpContext 並且 InRequestScope() 依賴於它。

我想你是對的。 你可以試試:

 Bind<IMyContext>().To<MyContext>()
     .InScope(ctx => this.Scope)
     .NamedLikeFactoryMethod((IContextFactory f) => f.GetContext());

this.Scope是您的 Test 類的屬性(任何引用類型都可以),其值在您的測試設置時初始化

或者,如果您仍想使用 InRequestScope 語法,您可以嘗試:

    public class MyPlugin : INinjectHttpApplicationPlugin
    {
        private Object Scope { get; } = true;

        public void Dispose(){}

        public INinjectSettings Settings { get; set; }

        public object GetRequestScope(IContext context)
        {
            return Scope;
        }

        public void Start() { }

        public void Stop() { }
    }

那么您的測試將類似於:

    public void RequestScopedContextAlwaysSame()
    {
        var kernel = new StandardKernel();
        kernel.Components.Add<INinjectHttpApplicationPlugin, MyPlugin>();
        kernel.Bind<IContextFactory>().ToFactory();
        kernel.Bind<IMyContext>().To<MyContext>()
            .InRequestScope()
            .NamedLikeFactoryMethod((IContextFactory f) => f.GetContext());
        kernel.Bind<IMyContext>().To<MyContext>()
            .InTransientScope()
            .NamedLikeFactoryMethod((IContextFactory f) => f.GetTransientContext());

        var factory = kernel.Get<IContextFactory>();
        //Act
        var context1 = factory.GetContext();
        var context2 = factory.GetContext();

        //Assert
        Assert.IsTrue(context1.Equals(context2));
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM