2013-10-08 2 views
2

У меня есть рабочая реализация CustomCredentialsAuth, реализованная в моем приложении ServiceStack. Я могу ударить URL с учетными данными auth, и он работает так, как ожидалось.Как я могу пройти тесты ServiceStack для проверки подлинности с помощью RestSharp?

В моих тестах, однако, у меня нет такой же удачи.

Я использую RestSharp, и если я отключу [Authenticate], я могу пройти все мои тесты.

Включение [Authenticate] и запуска тестов дают мне

Прогнозный: OK
Но был: Несанкционированное

Вот мой тест. Как я могу заставить RestSharp пройти аутентификацию для моих тестов?

using System; 
using System.Net; 
using FutureState.AppCore.Tests.Integration.Repositories.Fixtures; 
using NUnit.Framework; 
using RestSharp; 

namespace FutureState.AppCore.Tests.Functional.Services 
{ 
    [TestFixture] 
    public class UserServiceInterfaceTests 
    { 
     private RestSchemaValidator _restSchemaValidator; 
     private string _testLoginEmail; 
     private string _testLoginPassword; 

     [SetUp] 
     public void SetUp() 
     { 
      _restSchemaValidator = new RestSchemaValidator(); 
      _testLoginEmail = UserFixture.SystemAccount.Email; 
      _testLoginPassword = "password"; 

     } 

     [Test] 
     public void ShouldGetAListOfUsersAndReturnStatusOk() 
     { 
       // Setup 
       var client = new RestClient(ServiceTestAppHostBase.BaseUrl); 
       client.Authenticator = new HttpBasicAuthenticator(_testLoginEmail, _testLoginPassword); 
       var request = new RestRequest("https://stackoverflow.com/users/", Method.GET) { RequestFormat = DataFormat.Json }; 

       // Execute 
       var response = client.Execute(request); 

       // Assert 
       Assert.That(response.ErrorMessage, Is.Null); 
       Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); 
       _restSchemaValidator.ValidateResponse("ExpectedUsersResponse.json", response.Content); 
     } 

     [Test] 
     public void ShouldGetAUserAndReturnStatusOk() 
     { 
      // Setup 
      var expectedUserId = new Guid(UserFixture.FirstUserId); 
      var client = new RestClient(ServiceTestAppHostBase.BaseUrl); 
      client.Authenticator = new HttpBasicAuthenticator(_testLoginEmail, _testLoginPassword); 
      var request = new RestRequest("https://stackoverflow.com/users/" + expectedUserId, Method.GET) { RequestFormat = DataFormat.Json }; 

      // Execute 
      var response = client.Execute(request); 

      // Assert 
      Assert.That(response.ErrorMessage, Is.Null); 
      Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); 
      _restSchemaValidator.ValidateResponse("ExpectedUserResponse.json", response.Content); 
     } 
    } 
} 

Я использую пользовательский поставщик аутентификации:

public class CustomCredentialsAuthProvider : CredentialsAuthProvider 
{ 
    private readonly IUserService _userService; 
    private Guid _userId; 

    public CustomCredentialsAuthProvider (Container container) 
    { 
     _userService = container.Resolve<IUserService>(); 
    } 

    public override bool TryAuthenticate (IServiceBase authService, string email, string password) 
    { 
     var user = _userService.GetByEmailAddress(email); 
     user.Password = password; // Add the posted password to the user object before authenticating. 

     _userId = user.Id; 
     return _userService.CheckPassword(user); 
    } 

    public override void OnAuthenticated (IServiceBase authService, IAuthSession session, IOAuthTokens tokens, Dictionary<string, string> authInfo) 
    { 
     session.Id = _userId.ToString(); 

     //Important: You need to save the session! 
     authService.SaveSession(session, SessionExpiry); 
    } 
} 

И мой TestAppHostBase провод вверх AUTH, как это.

private void ConfigureAuth (Container container) 
{ 

    //Default route: /auth/{provider} 
    Plugins.Add(new AuthFeature(() => new AuthUserSession(), 
    new IAuthProvider[] { 
     new CustomCredentialsAuthProvider(container) 
    })); 

    //Default route: /register 
    Plugins.Add(new RegistrationFeature()); 

} 

Дальнейшее развитие, вызвав следующий код делает возвращающие для пользователя, но, очевидно, не передает данные сеанса для последующего RestRequest.

// Calling this returns TRUE for TryAuthenticate 
// But doesn't retain the session data for the subsequenet request. 
var container = EndpointHost.AppHost.TryResolve<Container>(); 
var authService = new AuthService(); 
var customCredentialsAuthProvider = new CustomCredentialsAuthProvider(container); 
customCredentialsAuthProvider.TryAuthenticate(authService, _testLoginEmail, _testLoginPassword); 
+0

Не могу обнаружить никаких проблем с этим кодом. Вы устанавливаете 'client.Authenticator' так же, как и мы, и регистрируете свой объект AuthFeature и пользовательский объект auth. Можете ли вы установить точку останова в «TryAuthenticate»? –

+0

@esker 'TryAuthenticate' даже не попадает. –

+0

Должен ли я действительно нажимать на 'auth? Username = system @ account.com и пароль = пароль' в тестовой установке для аутентификации? –

ответ

2

Так что получается самый лучший способ, которым мы могли бы придумать, чтобы решить эту проблему, чтобы использовать CookieContainer и передать его как часть клиента.

Сначала мы сделали базовый класс для нашего ServiceInterfaceTests

public class ServiceInterfaceTestBase 
{ 
    protected IRestClient Client; 
    protected void AuthenticateClient(string email, string password) 
    { 

     Client = new RestClient(ServiceTestAppHostBase.BaseUrl); 
     var login = new RestRequest("/auth", Method.POST); 
     login.AddParameter("username", email); 
     login.AddParameter("password", password); 

     var response = Client.Execute(login); 
     var cookieJar = new CookieContainer(); 

     if (response.StatusCode == HttpStatusCode.OK) 
     { 
      var cookie = response.Cookies.FirstOrDefault(); 
      cookieJar.Add(new Cookie(cookie.Name, cookie.Value, cookie.Path, cookie.Domain)); 
     } 

     Client.CookieContainer = cookieJar; 
    } 
} 

В ServiceInterfaceTests наследует от него

[TestFixture] 
public class UserServiceInterfaceTests : ServiceInterfaceTestBase 
{ 

Тогда в наших установках, мы называем метод аутентификации.

[SetUp] 
public void SetUp() 
{ 
    _restSchemaValidator = new RestSchemaValidator(); 
    _testLoginEmail = UserFixture.SystemAccount.Email; 
    _testLoginPassword = "password"; // the database contains a hashed password version of "password". 

    AuthenticateClient(_testLoginEmail, _testLoginPassword); 
} 

И, наконец, наш тест будет выглядеть

[Test] 
public void ShouldGetAListOfUsersAndReturnStatusOk() 
{ 
    // Setup 
    var request = new RestRequest("https://stackoverflow.com/users/", Method.GET) { RequestFormat = DataFormat.Json, }; 

    // Execute 
    var response = Client.Execute(request); 

    // Assert 
    Assert.That(response.ErrorMessage, Is.Null); 
    Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK)); 
    _restSchemaValidator.ValidateResponse("ExpectedUsersResponse.json", response.Content); 
    Trace.Write(response.Content); 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^