【问题标题】:Castle windsor to use a fakeiteasy object while Resolving in Unit testCastle Windsor 在单元测试中解析时使用 fakeiteasy 对象
【发布时间】:2025-11-25 22:20:06
【问题描述】:

我在 FakeItEasy 和 Castle Windsor 中都很菜鸟,这就是为什么我在搜索 Google 时遇到问题,因为我不知道要搜索的关键字。

现在问题来了

我正在上课

public class PersonService : IPersonService
{
    IMarriageHelper objIMarriageHelper;
    IPersonRepository objIPersonRepository;
    public PersonService(IMarriageHelper objMarriageHelper, IPersonRepository objPersonRepository)
    {
        this.objIMarriageHelper = objMarriageHelper;
        this.objIPersonRepository = objPersonRepository;
    }

}

现在我正在使用 Castle Windsor 在单元测试用例中解析我的 PersonService 类。

        var objContainer = new WindsorContainer();
        objContainer.Register(Component.For<PersonService>());
        objContainer.Register(Component.For<IMarriageHelper>().ImplementedBy<MarriageHelper>());
        objContainer.Register(Component.For<IPersonRepository>().ImplementedBy<PersonRepository>());
        var objPersonService = objContainer.Resolve<PersonService>();

现在的问题是我想在解析 PersonService 而不是 MarraigeHelper 时发送 PersonRepository 的假对象。

请帮我解决这个问题,因为我对此很陌生。

【问题讨论】:

  • 你也可以试试autofixture - 非常适合这份工作。

标签: asp.net unit-testing mocking inversion-of-control castle-windsor


【解决方案1】:

在温莎城堡中,当你将多个组件注册到同一个界面时,温莎会解析第一个或带有Default()标记的那个。

有很多方法可以解决您的问题。我将只指出其中的几个...

使用名称注册:

const string FAKE_REPOSITORY = "fake person repo";
var fakePersonRepository = A.Fake<IPersonRepository>();
objContainer.Register(Component.For<IPersonRepository>()
                               .Instance(fakePersonRepository)
                               .Named(FAKE_REPOSITORY));
const string PERSON_FOR_TEST = "person for test";
objContainer.Register(Component.For<PersonService>()
                               .DependsOn(Dependency.OnComponent(typeof(IPersonRepository), FAKE_REPOSITORY))
                               .Named(PERSON_FOR_TEST));

然后解决这个人服务:

var target = objContainer.Resolve<PersonService>(PERSON_FOR_TEST);

另一种选择是让您的 PersonService 依赖于 dynamic parameters 在这种情况下,您将 PersonService 解析为 fakePersonRepository

var target = objContainer.Resolve<PersonService>(<key name>, fakePersonRepository)

我可以考虑另外 3-4 个选项(工厂方法,这些方法之间的某种组合等等......)但是,我认为构建 PersonService 进行测试的最佳方法是在不使用 Windsor 魔法的情况下显式构建它/使用 windsor 仅用于解析 IMarriageHelper。 那么您的代码将更具可读性和易于维护。

【讨论】:

  • 非常感谢您的解释。我将立即实现代码并看看它是如何工作的。还有一个请求,你能指定其他3-4种方式的名称或一些关键词,以便我可以谷歌它并了解这些方式。
  • 当然:Factory method 允许您创建自定义创建方法。 Factory facility 与工厂方法非常相似。为测试创建Installer,它允许您覆盖设置...最后一个是:您可以在选项之间任意组合...