首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用中心DI逻辑进行单元测试和最小化“排列”阶段

使用中心DI逻辑进行单元测试和最小化“排列”阶段
EN

Stack Overflow用户
提问于 2017-11-27 10:59:24
回答 1查看 523关注 0票数 0

我在单元测试中遇到的唯一问题是,我的Arrange阶段(在Arrange-Act-Assert pattern中)相当长,因此出现了可维护性问题。我在测试类的构造函数中注册了几十个。有些测试类具有公共注册,我认为可以将所有这些注册移到一个中心位置,并在其上使用AssemblyInitialize属性(例如,这种方法将类似于Global.asaxStartup.cs中的注册部分)。如果要覆盖已注册的类型,它可以简单地重新注册它(在这种情况下,我的容器重写旧的注册类型)。然而,也会有一些额外的注册为一些测试课程。

这会是个糟糕的决定吗?如果是,为什么?

是否有任何第三方工具可以帮助我(也许以更好的方式)?

这样做,我的单元测试时间会受到很大打击吗?因为有些测试类只有少数注册。也许我应该用什么东西来忽略这些中央注册呢?

编辑:

样本代码:

代码语言:javascript
复制
private CustomersController controller;

public CustomersControllerTests()
{
    var container = ContainerFactory.GetContainer();
    MapperConfiguration autoMapperConfig = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile<DefaultMappingProfile>();
    });
    container.RegisterInstance(autoMapperConfig);
    container.Register<Common.Contracts.Mapper.IMapper, AutoMapperWrapped>(Lifetime.Singleton);
    container.Register<IProxy, BusinessProxy>();
    container.Register<IDataContext, FakeDataContext>();
    container.Register<IUnitOfWork, FakeUnitOfWork>();
    container.Register<ICustomerBusiness, CustomerBusiness>();
    //...Some more registrations
    controller = new CustomersController();
} 

[TestMethod]
public async Task GetCustomerById_ForNonExistingCustomer_ReturnsNotFound()
{
    //Act
    var result = await controller.GetCustomerById(0);

    //Assert
    Assert.IsInstanceOfType(result, typeof(NotFoundResult));
}

对于此测试方法,排列部分位于测试类的构造函数中,如下所示。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-27 11:30:10

你的单元测试是在测试单个单元--即类。理想情况下,任何依赖项都应该是模拟,在那里,您完全控制从它们返回的内容。

一个好的模式,尽管有些人不同意,是SUT模式。在高级单元测试课程中,Mark在Pluralsight (任何想要单元测试的人)中非常出色地解释了这一点,我试着把他们指向这个课程。

高级单元测试

SUT模式是一个流畅的API,您基本上使用它来创建测试(SUT)下的系统--即正在测试的类。这提高了测试的可读性,并保持了干燥(不要重复自己)。

快速示例

代码语言:javascript
复制
internal sealed class MySutBuilder
{
    private ISignInService _webServiceSignInService;


    public MySutBuilder()
    {
        _webServiceSignInService = new Mock<ISignInService>().Object;
    }

    public MySutBuilder WithSecurityAccess()
    {
        var authenticationMock = new Mock<ISignInService>();
        authenticationMock.Setup(m => m.SignIn(It.IsAny<GetDocumentContentRequest>()))
                    .Returns(SignInResult.Success(new ServiceUserContextMock()));

           _webServiceSignInService = authenticationMock.Object;

        return this;
    }

    public MyService Build()
    {
        MyService cut = new MyService(_webServiceSignInService);

        return cut;
    }
}

因此,我们的想法是在单元测试中使用SutBuilder来控制该类的依赖关系。如果将内容添加到构造函数中,那么只需要在测试中的一个位置修复它--但我猜这将取决于测试的滚动方式。

这是一段减少的代码,因此我们所拥有的类可以在每个类的5+依赖项下得到相当大的值。

单元测试使用

代码语言:javascript
复制
// arrange
var sut = new MySutBuilder()
    .WithSecrityAccess()
    .Build();

// act
var result = sut.DoSomething();

// assert
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47509323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档