4

I'm working through some Functional Tests on my app, and I think I'm getting pretty close. My problem is that when I run my first test, I get the error.

unable to connect to the remote server.

Expected: OK
But was: 0

I can confirm that if I put a breakpoint on the Assert, and then try to hit the BaseUrl in my browser, it is not found.

Here's my test.

[Test]
public void MyTestTest ()
{
    var client = new RestClient( ServiceTestAppHostBase.BaseUrl );
    // client.Authenticator = new HttpBasicAuthenticator( NUnitTestLoginName, NUnitTestLoginPassword );
    var request = new RestRequest( "/users/", Method.GET );
    request.RequestFormat = DataFormat.Json;
    var response = client.Execute( request );

    // do assertions on the response object now
    Assert.That( response.StatusCode, Is.EqualTo( HttpStatusCode.OK ) );
}

The AppServerTestSetup looks like this

[SetUpFixture]
public class AppServerTestSetup
{
    ServiceTestAppHostBase _appHost;

    [SetUp]
    public void SetUp()
    {
        _appHost = new ServiceTestAppHostBase();
        _appHost.Init();
        _appHost.Start(ServiceTestAppHostBase.BaseUrl);
    }

    [TearDown]
    public void TearDown()
    {
        _appHost.Dispose();
    }
}

And the ServiceTestAppHostBase looks like this.

public class ServiceTestAppHostBase : AppHostHttpListenerBase
{
    public const string BaseUrl = "http://localhost:8082/";
    public ServiceTestAppHostBase () : base( "OurApp.AppServer", typeof( UserServiceInterface ).Assembly ) { }

    public override void Configure ( Container container )
    {
        JsConfig.EmitCamelCaseNames = true;

        SetConfig( new EndpointHostConfig
        {
            MapExceptionToStatusCode = {
                { typeof( NotFoundException ), 404 }, // Map exception to 404 not found http response.
                { typeof( SystemAccountChangeException ), 405 } // Map exception to 405 method not allowed.
            }
        } );

        // Shared Container Registration
        AppHostContainerRegistrations.Register( container );

        // Setup the database
        var migrationRunner = container.Resolve<IMigrationRunner>();

        migrationRunner.CreateDatabase();
        migrationRunner.RunAll();
    }
}

note: I'm also using the AppHostContainerRegistrations in the main app, and it is working. I've also verified that it's being run in the test setup.

The AppHostContainerRegistrations (for reference) looks like this.

public class AppHostContainerRegistrations
{
    public static void Register(Container container)
    {
        // IOC Registration
        // Register base connection config
        var dbConnection = ConfigurationManager.ConnectionStrings["databaseConnection"];
        var databaseName = ConfigurationManager.AppSettings["databaseName"];

        // Register Sqlserver DbProvider
        container.Register<IDbConnectionProvider>( containr => new DbConnectionProvider( dbConnection.ConnectionString, dbConnection.ProviderName ) );
        container.Register<IDbProvider>( containr => new DbProvider( containr.Resolve<IDbConnectionProvider>(), databaseName ) );

        // Register repositories
        container.RegisterAs<DatabaseVersionRepository, IDatabaseVersionRepository>();
        container.RegisterAs<UserRepository, IUserRepository>();
        container.RegisterAs<GroupRepository, IGroupRepository>();
        container.RegisterAs<DeviceRepository, IDeviceRepository>();
        container.RegisterAs<SecuritySettingsRepository, ISecuritySettingsRepository>();

        // Register services
        container.RegisterAs<UserService, IUserService>();
        container.RegisterAs<GroupService, IGroupService>();
        container.RegisterAs<SecuritySettingsService, ISecuritySettingsService>();

        // Register everything else
        container.RegisterAs<PasswordHasher, IPasswordHasher>();
        container.RegisterAs<MigrationRunner, IMigrationRunner>();

        container.Register( new UserModel { Id = new Guid( "6C83DDEC-5E58-4F28-BDE2-61EBF1B49691" ) } );

    }
}

The reason we're doing our Db setup like this is because we have a single connection string and db name in the App.Config, and we rely on Transforms during deployment to setup the database.

Can anyone help me troubleshoot this issue?

Chase Florell
  • 46,378
  • 57
  • 186
  • 376
  • ServiceStack auto-wires and registers it's own services, i.e. so if `UserService` is a ServiceStack `Service` remove the registration. – mythz Oct 07 '13 at 20:23
  • @mythz When I remove the registration, The SetUp throws a `NullReferenceException` on `_appHost.Init();` – Chase Florell Oct 07 '13 at 20:42
  • and by "registration" I assume you're referring to `public ServiceTestAppHostBase () : base( "OurApp.AppServer", typeof( UserServiceInterface ).Assembly ) { }` – Chase Florell Oct 07 '13 at 20:44
  • I'm referring to remove all Service Registrations, e.g: `container.RegisterAs()` if UserService is a ServiceStack Service - but I can't tell if it is here as we can't see the code. – mythz Oct 07 '13 at 20:49
  • @mythz Oh, no those are Services and Repositories that are contained within our PCL. – Chase Florell Oct 07 '13 at 20:51
  • Our SS Service is called `UserServiceInterface` – Chase Florell Oct 07 '13 at 20:52
  • @mythz is there any further information that I might need to provide? – Chase Florell Oct 07 '13 at 20:56
  • Well the full HTTP Request/Response would be good (i.e. using Fiddler or WireShark). Any reason why you're not using [ServiceStack's Service Clients](https://github.com/ServiceStack/ServiceStack/wiki/C%23-client)? – mythz Oct 07 '13 at 20:58
  • @mythz I'm using RestSharp because that is what was decribed to me in another question. However, when changing to JsonServiceClient, I get `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:8082` – Chase Florell Oct 07 '13 at 21:16
  • Doesn't look like the HttpListener has started or has binded correctly. Try instead: `_appHost.Start("http://*:8082/");` also you should be in **Admin** node to run HttpListener. – mythz Oct 07 '13 at 21:19
  • @mythz admin mode? as in running VS as administrator? – Chase Florell Oct 07 '13 at 21:20
  • Yep, VS as administrator mode, if that's where you're running the test. Usually only required for *reserved port ranges*, but it doesn't look like the HttpListener has started, so it may be the cause. – mythz Oct 07 '13 at 21:23
  • Turns out it was Administrator Mode. I'm going to try and find a work around so this isn't an issue in our automated builds. – Chase Florell Oct 07 '13 at 21:42

1 Answers1

5

After a lengthy conversation with @mythz, it turns out that VS has to be run in Admin mode for the "AppHostHttpListenerBase" to run.

I also have to run Powershell as Admin when running ./build from the terminal.

Chase Florell
  • 46,378
  • 57
  • 186
  • 376