我有 4 个测试,分布在 3 个测试类中。如果我一个接一个地运行每个测试,它们都可以成功。但是运行所有(我认为是并行的?(除了第一个被解雇之外,它们都失败了?
我的测试需要相同的设置,所以我有一个所有测试都设置的夹具:
public class CompositionRootFixture
{
public Container Container { get; private set; } // Simple Injector Container
public CompositionRootFixture()
{
Container = new Container();
/* code removed for clearity */
Container.Verify();
}
}
并且在我的测试类中使用,如下所示:
public class CommandProcessorTests : IClassFixture<CompositionRootFixture>
{
private readonly CompositionRootFixture _fixture;
public CommandProcessorTests(CompositionRootFixture fixture)
{
_fixture = fixture;
}
[Fact]
public async Task TestExecutingUsingContainerForResolution()
{
var commands = _fixture.Container.GetInstance<IExecuteCommands>();
var command = new FakeCommandWithoutValidator();
await commands.Execute(command);
Assert.Equal("faked", command.ReturnValue);
}
}
我很难弄清楚如何使用IClassFixture<T>
,并且文档对设置它不是很有帮助。我使用的是最新的XUnit 2.0.0-beta5-build2785。
失败描述:
---- System.InvalidOperationException : The configuration is invalid. Creating the instance for type IHandleCommand<FakeCommandWithoutValidator> failed. The registered delegate for type IHandleCommand<FakeCommandWithoutValidator> threw an exception. The configuration is invalid. The type HandleFakeCommandWithoutValidator is directly or indirectly depending on itself.
-------- SimpleInjector.ActivationException : The registered delegate for type IHandleCommand<FakeCommandWithoutValidator> threw an exception. The configuration is invalid. The type HandleFakeCommandWithoutValidator is directly or indirectly depending on itself.
------------ SimpleInjector.ActivationException : The configuration is invalid. The type HandleFakeCommandWithoutValidator is directly or indirectly depending on itself.
---- The following constructor parameters did not have matching fixture data: CompositionRootFixture fixture
容器正在利用一个单一实例,该单例在执行的所有测试期间保持状态。
在每次测试之前初始化此单一实例。
看起来这可能与SimpleInjector中的一个错误有关:
http://simpleinjector.codeplex.com/discussions/259167
无论如何,问题出在依赖注入上。 如果该错误未修复,您可以尝试使用其他 IoC 容器,例如 Ninject,至少是为了进行比较。
我通过升级到xUnit 2.0.0并使用新的集合装置来解决此问题,这在他们的网站上进行了描述:http://xunit.github.io/docs/shared-context.html
尽管我没有使用 ClassFixture,但我的场景遇到了同样的问题(某些集成测试针对 EventStore 运行测试(。
xUnit 测试的想法是它可以并行运行每个事实。如果要避免这种情况,可以在某些程序集类上添加以下内容
[assembly: CollectionBehavior(DisableTestParallelization = true)]
它们将按顺序运行。
注意:理想情况下,应该避免这种情况,因为人们对以幂等和无状态的方式设计您的测试和代码非常感兴趣,事实上,我将所有测试都用作此类的子类,以拥有一个不错的给定 Then When 结构:
public abstract class Given_When_Then_Test
: IDisposable
{
protected Given_When_Then_Test()
{
Setup();
}
private void Setup()
{
Given();
When();
}
protected abstract void Given();
protected abstract void When();
public void Dispose()
{
Cleanup();
}
protected virtual void Cleanup()
{
}
}
我发现的事情:
- 当我使用 Autofac
IContainer
解析服务而不是先解析IComponentContext
然后解析我的服务时,我在并行运行的集成测试中遇到了错误。
希望这对某人有所帮助,但我必须确保每个单元/集成测试项目都直接将 Xunit 作为 Nuget 包引用。我认为拥有一个基础测试项目并通过它引用 Xunit 就足够了。事实证明,这会导致许多问题,例如不确定的测试或测试成功运行但并行失败。