繁体   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