System.IO.InvalidDataException:已设置ServiceStackHost.Instance(BasicAppHost)

时间:2017-07-18 13:48:47

标签: servicestack

当我尝试在servicestack Web服务上运行某些测试时,我收到错误消息。 我正在使用ServiceStack 4.5.8和Nunit 3.5。该解决方案最初是从ServiceStackVS模板创建的。

在许多测试中出现的错误是

   System.IO.InvalidDataException : ServiceStackHost.Instance has already been set (BasicAppHost)</br>
TearDown : System.NullReferenceException : Object reference not set to an instance of an object.</br>
   at ServiceStack.ServiceStackHost.Init()</br>
   at MyApp.Tests.EchoServiceUnitTests.OneTimeSetup() in </br>
C:\Repos\MyApp\Myapp\MyApp.Tests\EchoServiceUnitTests.cs:line 45 </br>
--TearDown</br>
   at MyApp.Tests.EchoServiceUnitTests.TestFixtureTearDown() in </br>C:\Repos\MyApp\MyApp\MyApp.Tests\EchoServiceUnitTests.cs:line 54

定期生成此错误的其中一项测试是

namespace Tests
{

    [TestFixture]
    public class EchoServiceUnitTests
        {

            private ServiceStackHost appHost;

            [OneTimeSetUp]
            public void OneTimeSetup()
                {
                    this.appHost = new  BasicAppHost(typeof(EchoService).Assembly).Init();
                }


            [OneTimeTearDown]
            public void TestFixtureTearDown()
                {
                    this.appHost.Dispose();

                }


            [Test]
            public void TestService()
                {
                    const string Message = "Hello";

                    var service = this.appHost.Container.Resolve <EchoService>();

                    var response = (EchoResponse)service.Any(new Echo
                                                                 {
                                                                     Message = Message
                                                                 });

                    Assert.That(response.Message,
                                Is.EqualTo(Message));
                }
        }
}

这项服务是

namespace ServiceInterface
{

    public class EchoService : Service
        {
              public object Any(Echo request)
                {
                    return new EchoResponse {Message = request.Message};
                }
      }
}

[Route("/Echo")]
[Route("/Echo/{Message}")]
public class Echo : IReturn<EchoResponse>
{

    public string Message { get; set; }

}

    public class EchoResponse : IHasResponseStatus
{
       public EchoResponse()
    {
        this.ResponseStatus = new ResponseStatus();
    }

    public string Message { get; set; }

    public ResponseStatus ResponseStatus { get; set; }

}

最后是我的apphost

namespace MyApplication
{
    using System;

    using Funq;

    using ServiceInterface;
    using ServiceModel.Validators;

    using ServiceStack;
    using ServiceStack.Admin;
    using ServiceStack.Api.Swagger;
    using ServiceStack.Caching;
    using ServiceStack.Configuration;
    using ServiceStack.Logging;
    using ServiceStack.Logging.NLogger;
    using ServiceStack.MsgPack;
    using ServiceStack.OrmLite;
    using ServiceStack.OrmLite.SqlServer.Converters;
    using ServiceStack.ProtoBuf;
    using ServiceStack.Razor;
    using ServiceStack.Validation;
    using ServiceStack.VirtualPath;
    using ServiceStack.Wire;


    public class AppHost : AppHostBase
        {

            public static ILog Log = LogManager.GetLogger(typeof(AppHost));

                public AppHost()
                : base("MyApp",
                       typeof(HelloService).Assembly) { }


            public override void Configure(Container container)
                {
                    LogManager.LogFactory = new NLogFactory();

                    Log = LogManager.GetLogger(this.GetType());

                    this.Plugins.Add(new RazorFormat());

                    this.Plugins.Add(new PostmanFeature());

                    this.Plugins.Add(new SwaggerFeature());

                    this.Plugins.Add(new AdminFeature());

                    var ormSettings = new AppSettings();

                    container.Register <ICacheClient>(new MemoryCacheClient());

                    var dbFactory = new OrmLiteConnectionFactory(ormSettings.GetString("SqlDbConnection"),
                                                                 SqlServerDialect.Provider);


                    dbFactory.RegisterConnection("Database2",
                                                 ormSettings.GetString("Sql2Connection"),
                                                 SqlServerDialect.Provider);

        SqlServerDialect.Provider.RegisterConverter<DateTime?>(new SqlServerDateTimeConverter());

        this.Plugins.Add(new RequestLogsFeature
                                         {
                                             RequestLogger = new CsvRequestLogger(files: new FileSystemVirtualPathProvider(this,
                                                                                                                           this.Config.WebHostPhysicalPath),
                                                                                  requestLogsPattern: "requestlogs/{year}-{month}/{year}-{month}-{day}.csv",
                                                                                  errorLogsPattern: "requestlogs/{year}-{month}/{year}-{month}-{day}-errors.csv",
                                                                                  appendEvery: TimeSpan.FromSeconds(1)),
                                             EnableRequestBodyTracking = true,
                                             EnableResponseTracking = true,
                                             EnableErrorTracking = true,
                                         });

                    this.Plugins.Add(new AutoQueryDataFeature
                                         {
                                             MaxLimit = 1000
                                         });

                    this.Plugins.Add(new AutoQueryFeature());

                    var sse = new ServerEventsFeature
                                  {
                                      StreamPath = "/event-stream",

                                      HeartbeatPath = "/event-heartbeat",

                                      UnRegisterPath = "/event-unregister",

                                      SubscribersPath = "/event-subscribers",

                                      LimitToAuthenticatedUsers = false,

                                      IdleTimeout = TimeSpan.FromSeconds(30),

                                      HeartbeatInterval = TimeSpan.FromSeconds(10),

                                      NotifyChannelOfSubscriptions = true,
                                  };

                    this.Plugins.Add(sse);
                    Plugins.Add(new AdminFeature());

                    Plugins.Add(new WireFormat());
                    Plugins.Add(new MsgPackFormat());
                    Plugins.Add(new ProtoBufFormat());

                }
        }
}

我尝试了各种各样的建议,包括让测试中的apphost静态,但似乎没有什么对我有用。然后我尝试了以下测试,它也产生了同样的错误,这表明apphost中有一些东西是错误的,但我看不出是什么。

        [TestFixture(Category = "AppHost")]
    public class AppHostTests
        {
            /// <summary>
            /// The app host doesnt throw exception.
            /// </summary>
            [Test]
            public void AppHostDoesntThrowException()
                {
                    var apphost = new AppHost();
                    Assert.That(() => apphost.Init(),
                                Throws.Nothing);
                }
        }

生成此错误的测试是否使用NCRUNCH(设置为一次运行一个)或者如果我使用resharpers运行所有测试。它通常是产生此错误的相同测试,尽管这似乎有所不同。在所有情况下,如果我然后手动运行测试,它们都会通过。

1 个答案:

答案 0 :(得分:2)

您只能在运行NCrunch测试的同时初始化并运行1个AppHost,而另一个AppHost仍在使用中。也许你可以尝试调试并设置一个断点,在尝试初始化另一个AppHost之前检查import struct data = [-24, -4, -19, 100,...,98, 0] unpacked = "" for d in data: unpacked += struct.pack("b", d) print unpacked 是否为null。

请注意,AppHostBase是一个ASP.NET Web App,如果它在与单元测试相同的项目中运行,可能会造成干扰。如果您想要集成测试,请使用AppSelfHostBase代替您要运行完整集成测试的BasicAppHost。