在 Controller 中声明构造函数继承 ControllerBase

Declaring constructor inside Controller inheriting ControllerBase

我正在开发使用 ASP.NET Core 2.1 的 Web 应用程序项目。在开发 API 的同时,我们还尝试使用 MSTest 框架对其进行单元测试。

我的控制器继承自 ControllerBase。在我的测试台中,我使用 Moq 框架模拟我的业务层。当我从测试方法调用 Controller 时,我需要将一个 Mocked Business 实例传递给控制器​​,我试图为其声明参数化构造函数。

测试用例运行良好,但我的正常流程受到干扰。我什至尝试同时使用参数化和无参数构造函数。

这适用于继承 APIController 的 Dot Framework。

public class BookingController: ControllerBase {
    BusinessManager business = new BusinessManager();
    //Non-Parameterized Constructor
    public BookingController() {}
    //Parameterized Constructor
    public BookingController(BusinessManager mockedBusiness) {
        this.business = mockedBusiness;
    }
}

从 UI 调用时应使用非参数化构造函数。 参数化应该只有在从测试台调用传递一些实例时才有效。

在原始代码中,

BusinessManager business = new BusinessManager();

将控制器与依赖项紧密耦合,被认为是一种代码味道。这就是为什么您最终不得不尝试变通以便能够单独测试控制器的原因。

使用explicit dependency principle并保留参数化构造函数

public class BookingController: ControllerBase {
    private readonly BusinessManager business;

    //Parameterized Constructor
    public BookingController(BusinessManager business) {
        this.business = business;
    }

    //...
}

Startup 中,向服务集合注册您的依赖项

public void ConfigureServices(IServiceCollection services) {

    //...

    services.AddScoped<BusinessManager>();

    //...

}

这将允许框架在正常流程中创建控制器时在 运行 时注入所需的依赖项,并且还允许控制器足够灵活,以便与您的模拟业务隔离进行测试实例.