1

単一ページ Web アプリ(.ASP MVC ではなく、ServiceStack の RazorFormat() MVC で提供される Web ページ)が機能するようになった後、サービスの(以前は合格していた)テストを実行しました。テストに失敗しました。Web アプリを再度テストしました(デバッグの実行、//localhost:1337/ResourceListブラウザーでの移動) : まだ動作しています。テストに何か問題がありますか?

エラーは次のとおりです。

Test Name:  TestResourceList
Test FullName:  [0-1015]ServiceWrapper.Test.TestSWrapperServices.TestResourceList
Test Source:    c:\Users\uname\Documents\Visual Studio 2012\Projects\ServiceWrapper\UnitTestProject1\ServiceTests.cs : line 96
Test Outcome:   Failed
Test Duration:  0:00:02.188

Result Message: 
System.Net.WebException : Unable to connect to the remote server
  ----> System.Net.Sockets.SocketException : No connection could be made because the target machine actively refused it 127.0.0.1:1337
Result StackTrace:  
at System.Net.HttpWebRequest.GetResponse()
at ServiceStack.ServiceClient.Web.ServiceClientBase.Send[TResponse](String httpMethod, String relativeOrAbsoluteUrl, Object request)
at ServiceStack.ServiceClient.Web.ServiceClientBase.Get[TResponse](IReturn`1 request)
at ServiceWrapper.Test.TestSWrapperServices.TestResourceList() in c:\Users\uname\Documents\Visual Studio 2012\Projects\ServiceWrapper\UnitTestProject1\ServiceTests.cs:line 98
--SocketException
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)

テストは次のとおりです。

namespace ServiceWrapper.Test
{
    [TestFixture]
    public class TestSWrapperServices
    {
        AppHost appHost;
        private const string ListeningOn = "http://*:1337/";
        public const string Host = "http://localhost:1337";
        private const string BaseUri = Host + "/";

        [TestFixtureSetUp]
        public void OnTestFixtureSetUp()
        {
            var appSettings = new AppSettings();
            var username = Environment.GetEnvironmentVariable("USERNAME");
            var userdomain = Environment.GetEnvironmentVariable("USERDOMAIN");

            AppHost.AppConfig = new AppConfig(new AppSettings());

            appHost = new AppHost();

            // initialize Service Server
            ServiceServer.SetUser(AppHost.AppConfig.UserName, AppHost.AppConfig.Password);
            ServiceServer.SetLog(String.Empty);

            try
            {
                appHost.Init();
                appHost.Start(ListeningOn);
            }
            catch (HttpListenerException ex)
            {
                if (ex.ErrorCode == 5)
                {
                    System.Diagnostics.Debug.WriteLine("You need to run the following command (as admin):");
                    System.Diagnostics.Debug.WriteLine("  netsh http add urlacl url={0} user={1}\\{2} listen=yes",
                        ListeningOn, userdomain, username);
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("ERROR: {0}: {1}", ex.GetType().Name, ex.Message);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine("ERROR: {0}: {1}", ex.GetType().Name, ex.Message);
            }
        }

        [TestFixtureTearDown]
        public void OnTestFixtureTearDown()
        {
            appHost.Dispose();
        }

        [Test]
        public void TestResourceList()
        {
            JsonServiceClient client = new JsonServiceClient(BaseUri);
            ResourceList response = client.Get(new ResourceList());
            Assert.Contains("Some Value", response.property);
        }
        [Test]
    }
}
4

1 に答える 1

3

最新の ServiceStack 3.9.55 にアップグレードしましたが、それでも機能しませんでした。それで、最初から健全性チェックをやり直しました。http://*:1337/nunit TestFixture ListeningOn があったときに、program.cs ListeningOn が持っていることがわかりました。http://localhost:1337/

urlacl を (管理者として) 確認していhttp://localhost:1337/ます:

    C:\Windows\system32>netsh http show urlacl url=http://localhost:1337/

    URL Reservations:
    -----------------

urlacl を (管理者として) 確認していhttp://*:1337/ます:

    C:\Windows\system32>netsh http show urlacl url=http://*:1337/

    URL Reservations:
    -----------------

        Reserved URL            : http://*:1337/
            User: DOMAIN\user
                Listen: Yes
                Delegate: No
                SDDL: D:(A;;GX;;;S-1-5-21-2595267603-2801715271-1705165942-1002)

私の以前のトラブルシューティングでは、2 つのプロジェクトの ListeningOn 値に一貫性がありませんでした。興味深いことに、http://*:1337/ を使用するとワイルドカード URL として機能しません。

add urlacl コマンドの作成に役立つ便利なコード スニペットを次に示します。また、リッスンしている正確な URL の便利な (!) 健全性チェックも提供します。

    Console.WriteLine("You need to run the following command:");
    Console.WriteLine("  netsh http add urlacl url={0} user={1}\\{2} listen=yes",
    ListeningOn, userdomain, username);

- - アップデート - -

ServiceStack をアップグレードすると、「接続がアクティブに拒否されました」というエラー メッセージが表示されなくなりました。値が統一されるListeningOnと、実際のエラー メッセージが表示されました。

Result Message: ServiceStack.ServiceClient.Web.WebServiceException : Service Unavailable
Result StackTrace:  
at ServiceStack.ServiceClient.Web.ServiceClientBase.ThrowWebServiceException[TResponse](Exception ex, String requestUri)
at ServiceStack.ServiceClient.Web.ServiceClientBase.ThrowResponseTypeException[TResponse](Object request, Exception ex, String requestUri)
at ServiceStack.ServiceClient.Web.ServiceClientBase.HandleResponseException[TResponse](Exception ex, Object request, String requestUri, Func`1 createWebRequest, Func`2 getResponse, TResponse& response)
at ServiceStack.ServiceClient.Web.ServiceClientBase.Send[TResponse](String httpMethod, String relativeOrAbsoluteUrl, Object request)
at ServiceStack.ServiceClient.Web.ServiceClientBase.Get[TResponse](IReturn`1 request)
at RemoteServerWrapper.Test.TestRSWrapperServices.TestDataList() in c:\Users\user\Documents\Visual Studio 2012\Projects\RemoteServerWrapper\UnitTestProject1\ServiceTests.cs:line 183

まだあいまいですが、少なくとも、実際の問題とはまったく異なるものを報告していません. そこで、次のように app.config にトレースを実装しました。

<configuration>

  <!-- ... other config settings ... -->

  <system.diagnostics>
    <sources>
      <source name="System.Net" tracemode="includehex" maxdatasize="1024">
        <listeners>
          <add name="System.Net"/>
          <add name="console"/>
        </listeners>
      </source>
      <source name="System.Net.HttpListener">
        <listeners>
          <add name="System.Net"/>
          <add name="console"/>
        </listeners>
      </source>
    </sources>
    <switches>
      <add name="System.Net" value="Verbose"/>
      <add name="System.Net.HttpListener" value="Verbose"/>
    </switches>
     <sharedListeners>
      <add name="console" 
        type="System.Diagnostics.ConsoleTraceListener" 
        initializeData="false"/>
      <add name="System.Net"
        type="System.Diagnostics.TextWriterTraceListener"
        initializeData="network.log"
      />
    </sharedListeners>
    <trace autoflush="true"/>
  </system.diagnostics>
</configuration>

より良いエラーメッセージが表示されました:

ERROR: [::1]:1337 Request not found: /datarequest?DataKey=some_key&startDate=20130701&endDate=20130708

OK - サービススタック ソースを取得する必要があるので、コードをステップ実行して、テストで「Not Found」が発生する理由を突き止めます。これは、「デバッグ/実行」してブラウザ経由でテストしたときに機能する場合です。RestHandler.FindMatchingRestPath(httpMethod, pathInfo, contentType)一致を返していないことが判明しました。うーん。何故ですか?AppHost は同じように宣言されています。それで、何が違うのですか?

残りのサービスは、プロジェクトのメイン アセンブリに存在します。「デバッグ/実行」から実行すると、デフォルトのアセンブリにサービスがあり、すべてが機能します。しかし、サービス アセンブリを参照として追加してテスト プロジェクトから実行すると、servicestack はそれらを見つけることができません。それらは、テスト プロジェクトに関連する既定の場所にはありません。そこで、program.cs の AppHost クラスに依存するのではなく、テスト ファイルの先頭に AppHost クラスを追加し、次のように宣言しました。

public class RSWrapperServicesAppHostHttpListener
            : AppHostHttpListenerBase
{
    public RSWrapperServicesAppHostHttpListener()
        : base("RSWrapper Services Tests", typeof(DataRequestService).Assembly) { } 

// 'DataRequestService' is a random rest service class, 
// defined in the referenced services assembly

}

これで ServiceStack は問題なく動作し、テストは再び機能するようになりました。

彼らはどのように働いたのですか?もともと、すべてが 1 つのプロジェクトにすべてごちゃまぜにされていました。物事を別々のアセンブリ、つまり DTO、サービス、ビジネス ロジック、およびテストに分離したら、それを壊しました。しかし、UI を動かしながら単体テストを一時的に保留していたので、すぐには気がつきませんでした。

于 2013-07-11T16:35:30.933 に答える