所以我試圖建立一個端到端的集成測試套件與RavenDB和ServiceStack,但我遇到了一個很奇怪的問題,即驗證不上一些要求運行。這真的很奇怪,我不確定我做錯了什麼。我正在使用NCrunch。有時測試通過,有時失敗。ServiceStack驗證並非總是射擊
希望這是一個簡單的辦法和一些骨爲首我做的。
,你可以下載http://github.com/khalidabuhakmeh/endtoend
整個項目不需要比VS2012和NuGet包還原啓用的任何其他。
更新:我決定在NCrunch和Resharper Test Runner中都運行這兩個程序,兩者都給出相同的結果[見下圖]。
UPDATE UPDATE:我認爲它可能是XUnit,所以我試圖使用NUnit。不,仍然是同樣的問題。
**另一個更新:在控制檯將寫入按user1901853的要求。這是結果「
最新:在RequestFilters越來越消滅了,我不知道爲什麼看起來這可能是一個線程問題,但我看不到的地方。 。
我APPHOST使用AppHostListenerBase
using EndToEnd.Core;
using Funq;
using Raven.Client;
using ServiceStack.ServiceInterface.Validation;
using ServiceStack.WebHost.Endpoints;
namespace EndToEnd
{
public class TestAppHost
: AppHostHttpListenerBase
{
private readonly IDocumentStore _documentStore;
public TestAppHost(IDocumentStore documentStore)
: base("Test AppHost Api", typeof(TestAppHost).Assembly)
{
_documentStore = documentStore;
}
public override void Configure(Container container)
{
ServiceStack.Text.JsConfig.EmitCamelCaseNames = true;
// Register RavenDB things
container.Register(_documentStore);
container.Register(c =>
{
var db = c.Resolve<IDocumentStore>();
return db.OpenSession();
}).ReusedWithin(ReuseScope.Request);
Plugins.Add(new ValidationFeature());
container.RegisterValidators(typeof(CreateWidgetValidator).Assembly);
// todo: register all of your plugins here
AuthConfig.Start(this, container);
}
}
}
我對我所有的測試基礎測試類看起來是這樣的:
using Raven.Client;
using Raven.Client.Indexes;
using Raven.Tests.Helpers;
using ServiceStack.Authentication.RavenDb;
using ServiceStack.ServiceClient.Web;
using ServiceStack.ServiceInterface.Auth;
namespace EndToEnd
{
public abstract class ServiceStackTestBase
: RavenTestBase
{
protected IDocumentStore DocumentStore { get; set; }
protected TestAppHost Host { get; set; }
protected JsonServiceClient Client { get; set; }
protected const string ListeningOn = "http://localhost:1337/";
protected string Username { get { return "testuser"; } }
protected string Password { get { return "password"; } }
protected ServiceStackTestBase()
{
DocumentStore = NewDocumentStore();
IndexCreation.CreateIndexes(typeof(ServiceStackTestBase).Assembly, DocumentStore);
IndexCreation.CreateIndexes(typeof(RavenUserAuthRepository).Assembly, DocumentStore);
Host = new TestAppHost(DocumentStore);
Host.Init();
Host.Start(ListeningOn);
Client = new JsonServiceClient(ListeningOn)
{
AlwaysSendBasicAuthHeader = true,
UserName = Username,
Password = Password
};
RegisterUser();
WaitForIndexing(DocumentStore);
}
private void RegisterUser()
{
Client.Send(new Registration
{
UserName = Username,
Password = Password,
DisplayName = "Test User",
Email = "[email protected]",
FirstName = "test",
LastName = "user"
});
}
public override void Dispose()
{
DocumentStore.Dispose();
Host.Dispose();
}
}
}
我的測試類是這樣的:
using System;
using EndToEnd.Core;
using FluentAssertions;
using ServiceStack.FluentValidation;
using ServiceStack.ServiceClient.Web;
using ServiceStack.ServiceInterface.Auth;
using Xunit;
namespace EndToEnd
{
public class RegistrationTests
: ServiceStackTestBase
{
[Fact]
public void Throws_validation_exception_when_bad_widget()
{
var validator = Host.Container.Resolve<IValidator<CreateWidget>>();
validator.Should().NotBeNull();
try
{
var response = Client.Post(new CreateWidget
{
Name = null
});
// It get's here every once in a while
throw new Exception("Should Not Get Here!");
}
catch (WebServiceException wex)
{
wex.StatusCode.Should().Be(400);
wex.ErrorMessage.Should().Be("'Name' should not be empty.");
}
}
}
}
我的代碼查找服務是這樣的:
using System;
using Raven.Client;
using ServiceStack.FluentValidation;
using ServiceStack.ServiceHost;
using ServiceStack.ServiceInterface;
using ServiceStack.ServiceInterface.ServiceModel;
namespace EndToEnd.Core
{
[Authenticate]
public class WidgetsService
: Service
{
private readonly IDocumentSession _session;
public WidgetsService(IDocumentSession session)
{
_session = session;
}
public CreateWidgetResponse Post(CreateWidget input)
{
var widget = new Widget { Name = input.Name };
_session.Store(widget);
_session.SaveChanges();
return new CreateWidgetResponse { Widget = widget };
}
}
[Route("/widgets", "POST")]
public class CreateWidget : IReturn<CreateWidgetResponse>
{
public string Name { get; set; }
}
public class CreateWidgetResponse
{
public CreateWidgetResponse()
{
ResponseStatus = new ResponseStatus();
}
public Widget Widget { get; set; }
public ResponseStatus ResponseStatus { get; set; }
}
public class Widget
{
public Widget()
{
Created = DateTimeOffset.UtcNow;
}
public string Id { get; set; }
public string Name { get; set; }
public DateTimeOffset Created { get; set; }
}
public class CreateWidgetValidator : AbstractValidator<CreateWidget>
{
public CreateWidgetValidator()
{
RuleFor(m => m.Name).NotEmpty();
}
}
}
克隆你的回購,可以完全複製你所說的。試圖找到一些模式。你有沒有嘗試啓用日誌?我想知道POST請求是否被緩存,因爲當你的'Throws_validation_exception_when_bad_widget'首先運行時,它會通過。當其他兩個之一運行時,它會失敗。 – 2013-03-17 15:54:25
這可能是有道理的,有沒有辦法關閉緩存? – 2013-03-18 17:10:20
實際上只是雙重檢查,我沒有註冊一個緩存提供程序,我記得請求過濾器「有時」被清除。 – 2013-03-18 17:18:47