在单元测试班中使用Castle Windsor

时间:2016-04-28 19:35:14

标签: c# .net unit-testing castle-windsor

我是温莎城堡的菜鸟。我正在构建一个使用Entity Framework 6和Castle Windsor的应用程序,以及一个MSTest Unit Test类。我的应用程序中有一个实现IWindsorInstaller的类。我的单元测试类看起来像这样:

[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
}

单元测试项目中还有一个安装程序类,如下所示:

public class TestsInstaller : IWindsorInstaller {
    public void Install( IWindsorContainer container, IConfigurationStore store ) {
        container.Install( new RecipeManager.RepositoriesInstaller() );
    }
}

当我进入单元测试会话窗口&尝试运行所有测试,第一个成功,我得到其余的堆栈跟踪:

  

无法创建类UnitTests.DatabaseTests的实例。错误:Castle.MicroKernel.ComponentRegistrationException:无法注册组件RecipeManager.DAL.CategoryRepository。已有一个具有该名称的组件。您想要修改现有组件吗?如果没有,请确保指定唯一的名称..       在Castle.MicroKernel.SubSystems.Naming.DefaultNamingSubSystem.Register(IHandler处理程序)      在Castle.MicroKernel.DefaultKernel.AddCustomComponent(ComponentModel模型)      在Castle.MicroKernel.DefaultKernel.Register(IRegistration []注册)      在Castle.Windsor.WindsorContainer.Register(IRegistration []注册)      在RecipeManager.RepositoriesInstaller.Install(IWindsorContainer容器,IConfigurationStore商店)的C:\ Users \ Tony \ documents \ visual studio 2015 \ Projects \ RecipeManager \ ManageRecipes \ RepositoriesInstaller.cs:第10行      在Castle.Windsor.WindsorContainer.Install(IWindsorInstaller []安装程序,DefaultComponentInstaller范围)      在Castle.Windsor.WindsorContainer.Install(IWindsorInstaller []安装程序)      位于C:\ Users \ Tony \ documents \ visual studio 2015 \ Projects \ RecipeManager \ UnitTests \ TestsInstaller.cs中的UnitTests.TestsInstaller.Install(IWindsorContainer容器,IConfigurationStore商店):第8行      在Castle.Windsor.Installer.AssemblyInstaller.Install(IWindsorContainer容器,IConfigurationStore商店)      在Castle.Windsor.WindsorContainer.Install(IWindsorInstaller []安装程序,DefaultComponentInstaller范围)      在Castle.Windsor.WindsorContainer.Install(IWindsorInstaller []安装程序)      位于C:\ Users \ Tony \ documents \ visual studio 2015 \ Projects \ RecipeManager \ UnitTests \ DatabaseTests.cs:第17行的UnitTests.DatabaseTests..ctor()中

如果我一次运行一个单元测试,它们都会成功。我打算建立很多测试,所以我真的宁愿能够同时运行它们。我该如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

在您的测试类中,创建一个字段。

private WindsorContainer Container;

(替换现有的静态字段。)

然后,将其添加到您的测试类:

[TestInitialize]
public void SetUp()
{
    Container = new WindsorContainer();
    // register your dependencies
}

[TestCleanup]
public void Cleanup()
{
    Container.Dispose();
}
每次测试后,

[TestInitialize]在测试之前运行[TestCleanup] 这样,您不会为每个测试重用相同的容器,并尝试使用该容器重新注册相同的依赖项。在每次测试运行之前,您将创建一个新容器。如果您需要为每个测试使用相同的依赖项,则可以在Setup()中注册它们。或者,如果需要,您可以在测试方法中注册它们。

答案 1 :(得分:1)

要对此答案进行一些升级: 我创建了一个基础RepositoryTest类,其中包含Windsor容器逻辑。该类成为所有单元测试类的基础。

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>();