在单元测试中使用 Castle Windsor Class
Using Castle Windsor in Unit Test Class
我是温莎城堡的菜鸟。我正在构建一个使用 Entity Framework 6 和 Castle Windsor 以及 MSTest 单元测试 class 的应用程序。我的应用程序中有一个 class 实现了 IWindsorInstaller
。我的单元测试 class 看起来像这样:
[TestClass]
public class DatabaseTests {
static readonly WindsorContainer Container = new WindsorContainer();
public DatabaseTests() {
Container.Install( FromAssembly.This() );
}
[TestMethod]
public void FirstTest() {
// Test statements
}
[TestMethod]
public void SecondTest() {
// Test statements
}
// Other tests
}
单元测试项目中还有一个安装程序 class,如下所示:
public class TestsInstaller : IWindsorInstaller {
public void Install( IWindsorContainer container, IConfigurationStore store ) {
container.Install( new RecipeManager.RepositoriesInstaller() );
}
}
当我进入单元测试会话时 window 并尝试 运行 所有测试,第一个成功,其余的我得到这个堆栈跟踪:
Unable to create instance of class UnitTests.DatabaseTests. Error: Castle.MicroKernel.ComponentRegistrationException: Component RecipeManager.DAL.CategoryRepository could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name..
at Castle.MicroKernel.SubSystems.Naming.DefaultNamingSubSystem.Register(IHandler handler)
at Castle.MicroKernel.DefaultKernel.AddCustomComponent(ComponentModel model)
at Castle.MicroKernel.DefaultKernel.Register(IRegistration[] registrations)
at Castle.Windsor.WindsorContainer.Register(IRegistration[] registrations)
at RecipeManager.RepositoriesInstaller.Install(IWindsorContainer container, IConfigurationStore store) in C:\Users\Tony\documents\visual studio 2015\Projects\RecipeManager\ManageRecipes\RepositoriesInstaller.cs:line 10
at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers, DefaultComponentInstaller scope)
at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers)
at UnitTests.TestsInstaller.Install(IWindsorContainer container, IConfigurationStore store) in C:\Users\Tony\documents\visual studio 2015\Projects\RecipeManager\UnitTests\TestsInstaller.cs:line 8
at Castle.Windsor.Installer.AssemblyInstaller.Install(IWindsorContainer container, IConfigurationStore store)
at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers, DefaultComponentInstaller scope)
at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers)
at UnitTests.DatabaseTests..ctor() in C:\Users\Tony\documents\visual studio 2015\Projects\RecipeManager\UnitTests\DatabaseTests.cs:line 17
如果我 运行 一次测试一个单元,它们都会成功。我打算构建大量测试,所以我真的希望能够 运行 一次完成所有测试。我该如何解决这个问题?
在您的测试中 class,创建一个字段。
private WindsorContainer Container;
(替换现有的静态字段。)
然后,将此添加到您的测试中 class:
[TestInitialize]
public void SetUp()
{
Container = new WindsorContainer();
// register your dependencies
}
[TestCleanup]
public void Cleanup()
{
Container.Dispose();
}
[TestInitialize]
运行 每次测试前,[TestCleanup]
每次测试后。
这样,您就不会为每个测试重复使用相同的容器,也不会尝试向该容器重新注册相同的依赖项。在每个测试 运行 之前,您将创建一个新容器。如果您需要为每个测试使用相同的依赖项,您可以在 Setup()
中注册它们。或者,如果需要,您可以在测试方法中注册它们。
要对此答案进行一些升级:
我创建了一个包含 Windsor 容器逻辑的 Base RepositoryTest class。 class 成为所有单元测试 class 的根。
public abstract class RepositoryTestBase
{
private static IWindsorContainer windsorContainer { get; set; }
private static IMapper mapper { get; set; }
protected static IWindsorContainer WindsorContainer
{
get
{
if (windsorContainer == null)
{
WindsorContainerManager.ConfigureWindsor(Assembly.GetExecutingAssembly());
windsorContainer = WindsorContainerManager.Container;
}
return windsorContainer;
}
}
protected IMapper Mapper
{
get
{
if (mapper == null)
{
mapper = WindsorContainer.Resolve<IMapper>();
}
return mapper;
}
}
public static T GetResolved<T>()
{
return WindsorContainer.Resolve<T>();
}
}
[TestFixture, Category("UnitTest")]
public class AccountRepositoryTests : RepositoryTestBase
{
private IAccountRepository accountRepo = GetResolved<IAccountRepository>();
private IContactRepository contactRepo = GetResolved<IContactRepository>();
我是温莎城堡的菜鸟。我正在构建一个使用 Entity Framework 6 和 Castle Windsor 以及 MSTest 单元测试 class 的应用程序。我的应用程序中有一个 class 实现了 IWindsorInstaller
。我的单元测试 class 看起来像这样:
[TestClass]
public class DatabaseTests {
static readonly WindsorContainer Container = new WindsorContainer();
public DatabaseTests() {
Container.Install( FromAssembly.This() );
}
[TestMethod]
public void FirstTest() {
// Test statements
}
[TestMethod]
public void SecondTest() {
// Test statements
}
// Other tests
}
单元测试项目中还有一个安装程序 class,如下所示:
public class TestsInstaller : IWindsorInstaller {
public void Install( IWindsorContainer container, IConfigurationStore store ) {
container.Install( new RecipeManager.RepositoriesInstaller() );
}
}
当我进入单元测试会话时 window 并尝试 运行 所有测试,第一个成功,其余的我得到这个堆栈跟踪:
Unable to create instance of class UnitTests.DatabaseTests. Error: Castle.MicroKernel.ComponentRegistrationException: Component RecipeManager.DAL.CategoryRepository could not be registered. There is already a component with that name. Did you want to modify the existing component instead? If not, make sure you specify a unique name.. at Castle.MicroKernel.SubSystems.Naming.DefaultNamingSubSystem.Register(IHandler handler) at Castle.MicroKernel.DefaultKernel.AddCustomComponent(ComponentModel model) at Castle.MicroKernel.DefaultKernel.Register(IRegistration[] registrations) at Castle.Windsor.WindsorContainer.Register(IRegistration[] registrations) at RecipeManager.RepositoriesInstaller.Install(IWindsorContainer container, IConfigurationStore store) in C:\Users\Tony\documents\visual studio 2015\Projects\RecipeManager\ManageRecipes\RepositoriesInstaller.cs:line 10 at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers, DefaultComponentInstaller scope) at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers) at UnitTests.TestsInstaller.Install(IWindsorContainer container, IConfigurationStore store) in C:\Users\Tony\documents\visual studio 2015\Projects\RecipeManager\UnitTests\TestsInstaller.cs:line 8 at Castle.Windsor.Installer.AssemblyInstaller.Install(IWindsorContainer container, IConfigurationStore store) at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers, DefaultComponentInstaller scope) at Castle.Windsor.WindsorContainer.Install(IWindsorInstaller[] installers) at UnitTests.DatabaseTests..ctor() in C:\Users\Tony\documents\visual studio 2015\Projects\RecipeManager\UnitTests\DatabaseTests.cs:line 17
如果我 运行 一次测试一个单元,它们都会成功。我打算构建大量测试,所以我真的希望能够 运行 一次完成所有测试。我该如何解决这个问题?
在您的测试中 class,创建一个字段。
private WindsorContainer Container;
(替换现有的静态字段。)
然后,将此添加到您的测试中 class:
[TestInitialize]
public void SetUp()
{
Container = new WindsorContainer();
// register your dependencies
}
[TestCleanup]
public void Cleanup()
{
Container.Dispose();
}
[TestInitialize]
运行 每次测试前,[TestCleanup]
每次测试后。
这样,您就不会为每个测试重复使用相同的容器,也不会尝试向该容器重新注册相同的依赖项。在每个测试 运行 之前,您将创建一个新容器。如果您需要为每个测试使用相同的依赖项,您可以在 Setup()
中注册它们。或者,如果需要,您可以在测试方法中注册它们。
要对此答案进行一些升级: 我创建了一个包含 Windsor 容器逻辑的 Base RepositoryTest class。 class 成为所有单元测试 class 的根。
public abstract class RepositoryTestBase
{
private static IWindsorContainer windsorContainer { get; set; }
private static IMapper mapper { get; set; }
protected static IWindsorContainer WindsorContainer
{
get
{
if (windsorContainer == null)
{
WindsorContainerManager.ConfigureWindsor(Assembly.GetExecutingAssembly());
windsorContainer = WindsorContainerManager.Container;
}
return windsorContainer;
}
}
protected IMapper Mapper
{
get
{
if (mapper == null)
{
mapper = WindsorContainer.Resolve<IMapper>();
}
return mapper;
}
}
public static T GetResolved<T>()
{
return WindsorContainer.Resolve<T>();
}
}
[TestFixture, Category("UnitTest")]
public class AccountRepositoryTests : RepositoryTestBase
{
private IAccountRepository accountRepo = GetResolved<IAccountRepository>();
private IContactRepository contactRepo = GetResolved<IContactRepository>();