C# 使用Moq和模拟设置进行IConfiguration的单元测试控制器返回null

C# 使用Moq和模拟设置进行IConfiguration的单元测试控制器返回null,c#,unit-testing,configuration,moq,C#,Unit Testing,Configuration,Moq,单元测试webapi的新手。 我正在编写一个单元测试来测试控制器,我必须模拟Iconfiguration。appsettings,json有一个名为“appsettings”的部分,我试图模拟它 此外,mock.setup在控制器中返回null值,导致其失败 这是我的控制器: private readonly ILogger _logger; private readonly IConfiguration _configuration; private readonly

单元测试webapi的新手。 我正在编写一个单元测试来测试控制器,我必须模拟Iconfiguration。appsettings,json有一个名为“appsettings”的部分,我试图模拟它

此外,mock.setup在控制器中返回null值,导致其失败

这是我的控制器:

    private readonly ILogger _logger;
    private readonly IConfiguration _configuration;
    private readonly ICarPairingTable PairingTable;
    private readonly ICarDealerSettingsTable DealerSettingsTable;
    static AppSettings appSettings = null;
    public CarController(IConfiguration configuration, ICarPairingTable carPairingTable, ICarDealerSettingsTable settingsTable)
    {
        _configuration = configuration;
        appSettings = configuration.Get<AppSettingsModel>().AppSettings;
        PairingTable = carPairingTable;
        DealerSettingsTable = settingsTable;
    }

    [HttpGet]
    public ActionResult Get(string id){
        string DealerId ="";


                DealerId = PairingTable.GetDealerId(id).Result;
                if (string.IsNullOrEmpty(DealerId))
                {
                    result = new ReturnResult
                    {
                        status = "Fail",
                        data = "ID is invalid"
                    };
                    return NotFound(result);
                }



            SettingsInfo info = DealerSettingsTable.GetSettingsInfo(DealerId).Result;
            if (info == null)
            {
                result = new ReturnResult
                {
                    status = "Fail",
                    data = "Not Found
                };
                return NotFound(result);

            }
            result = new ReturnResult
            {
                status = "Success",
                data = info
            };
            return Ok(result);
    }
专用只读ILogger\u记录器;
专用只读IConfiguration\u配置;
专用只读ICarPairingTable配对表;
私有只读ICarDealerSettingsTable DealerSettingsTable;
静态AppSettings-AppSettings=null;
公共车辆控制器(IConfiguration配置、ICarPairingTable carPairingTable、iCardalerSettings稳定设置)
{
_配置=配置;
appSettings=configuration.Get().appSettings;
PairingTable=carPairingTable;
经销商设置表=设置稳定;
}
[HttpGet]
公共操作结果获取(字符串id){
字符串DealerId=“”;
DealerId=PairingTable.GetDealerId(id).Result;
if(string.IsNullOrEmpty(DealerId))
{
结果=新返回结果
{
status=“Fail”,
data=“ID无效”
};
返回未找到(结果);
}
SettingsInfo info=DealerSettingsTable.GetSettingsInfo(DealerId).Result;
if(info==null)
{
结果=新返回结果
{
status=“Fail”,
data=“未找到
};
返回未找到(结果);
}
结果=新返回结果
{
status=“Success”,
数据=信息
};
返回Ok(结果);
}
下面是我的单元测试:

   [Fact]
    public void Test1()
    {
        var mockConfig = new Mock<IConfiguration>();
        var configurationSection = new Mock<IConfigurationSection>();

        configurationSection.Setup(a => a.Value).Returns("testvalue");
        mockConfig.Setup(a => a.GetSection("AppSettings")).Returns(configurationSection.Object);

        var mock1 = new Mock<ICarPairingTable>();

        mock1.Setup(p => p.GetDealerId("456")).ReturnsAsync("123");
        var mock2 = new Mock<ICarDealerSettingsTable>();
        SettingsInfo mockSettings = new SettingsInfo()
        {
            DealerId = "123",

            Name="Dealer1"
        };
        mock2.Setup(p => p.GetSettingsInfo("123")).ReturnsAsync(()=>mockSettings);

        CarController controller = new CarController(mockConfig.Object,  mock1.Object, mock2.Object);
        var result = controller.Get("456");

        //Dont know what to assert

    }
[事实]
公共void Test1()
{
var mockConfig=new Mock();
var configurationSection=new Mock();
configurationSection.Setup(a=>a.Value).返回(“testvalue”);
mockConfig.Setup(a=>a.GetSection(“AppSettings”))。返回(configurationSection.Object);
var mock1=新Mock();
mock1.Setup(p=>p.GetDealerId(“456”)).ReturnsAsync(“123”);
var mock2=新Mock();
SettingsInfo mockSettings=新设置sinfo()
{
DealerId=“123”,
Name=“经销商1”
};
mock2.Setup(p=>p.GetSettingsInfo(“123”)).ReturnsAsync(()=>mockSettings);
CarController=newcarcontroller(mockConfig.Object、mock1.Object、mock2.Object);
var结果=controller.Get(“456”);
//不知道该断言什么
}

编写了单元测试,但不确定我的方法是否正确,我们将非常感谢您的帮助。

这更像是一个包装在一个文档中的设计问题

确实不应该注入
i配置
。根据控制器使用配置的方式,您应该在启动时向服务集合注册设置

Startup.ConfigureServices

因此,现在在单独对控制器进行单元测试时,可以初始化所需类的实例,并在执行单元测试时提供

参考文献

您似乎还混合了异步等待和阻塞调用,如
.Result

我建议您将操作始终异步

[HttpGet]
public async Task<ActionResult> Get(string id){
    string DealerId = await PairingTable.GetDealerId(id);
    if (string.IsNullOrEmpty(DealerId)) {
        var result = new ReturnResult {
            status = "Fail",
            data = "ID is invalid"
        };
        return NotFound(result);
    }

    SettingsInfo info = await DealerSettingsTable.GetSettingsInfo(DealerId);
    if (info == null) {
        var result = new ReturnResult {
            status = "Fail",
            data = "Not Found"
        };
        return NotFound(result);
    }
    var result = new ReturnResult {
        status = "Success",
        data = info
    };
    return Ok(result);
}
[HttpGet]
公共异步任务

这样,最终可以正确安排单元测试,以验证预期行为

[Fact]
public async Task Should_Return_Ok_ReturnRsult() {
    //Arrange
    var id = "456";
    var dealerId = "123";
    SettingsInfo expected = new SettingsInfo() {
        DealerId = dealerId,
        Name="Dealer1"
    };

    var pairingMock = new Mock<ICarPairingTable>();
    pairingMock.Setup(p => p.GetDealerId(id)).ReturnsAsync(dealerId);

    var dealerSettingsMock = new Mock<ICarDealerSettingsTable>();
    dealerSettingsMock.Setup(p => p.GetSettingsInfo(dealerId)).ReturnsAsync(() => expected);

    CarController controller = new CarController(new AppSettings(),  pairingMock.Object, dealerSettingsMock.Object);

    //Act
    var actionResult = await controller.Get(id);
    var actual = actionResult as OkObjectResult;

    //Assert (using FluentAssertions)

    actual.Should().NotBeNull();

    actual.Value.Should().BeOfType<ReturnResult>();

    var actualResult = actual.Value as ReturnResult;

    actualResult.data.Should().BeEquivalentTo(expected);        
}
[事实]
公共异步任务应\u返回\u确定\u返回结果(){
//安排
var id=“456”;
var dealerId=“123”;
SettingsInfo应为=新的SettingsInfo(){
DealerId=DealerId,
Name=“经销商1”
};
var pairingMock=new Mock();
pairingMock.Setup(p=>p.GetDealerId(id)).ReturnsAsync(dealerId);
var dealerSettingsMock=new Mock();
dealerSettingsMock.Setup(p=>p.GetSettingsInfo(dealerId)).returnsSync(()=>expected);
CarController=new CarController(new AppSettings(),pairingMock.Object,dealerSettingsMock.Object);
//表演
var actionResult=await controller.Get(id);
var actual=作为OkObjectResult的actionResult;
//断言(使用FluentAssertions)
实际的.Should().NotBeNull();
实际.Value.Should().BeOfType();
var actualResult=返回结果的实际值;
actualResult.data.Should().beequivalento(预期);
}
[HttpGet]
public async Task<ActionResult> Get(string id){
    string DealerId = await PairingTable.GetDealerId(id);
    if (string.IsNullOrEmpty(DealerId)) {
        var result = new ReturnResult {
            status = "Fail",
            data = "ID is invalid"
        };
        return NotFound(result);
    }

    SettingsInfo info = await DealerSettingsTable.GetSettingsInfo(DealerId);
    if (info == null) {
        var result = new ReturnResult {
            status = "Fail",
            data = "Not Found"
        };
        return NotFound(result);
    }
    var result = new ReturnResult {
        status = "Success",
        data = info
    };
    return Ok(result);
}
[Fact]
public async Task Should_Return_Ok_ReturnRsult() {
    //Arrange
    var id = "456";
    var dealerId = "123";
    SettingsInfo expected = new SettingsInfo() {
        DealerId = dealerId,
        Name="Dealer1"
    };

    var pairingMock = new Mock<ICarPairingTable>();
    pairingMock.Setup(p => p.GetDealerId(id)).ReturnsAsync(dealerId);

    var dealerSettingsMock = new Mock<ICarDealerSettingsTable>();
    dealerSettingsMock.Setup(p => p.GetSettingsInfo(dealerId)).ReturnsAsync(() => expected);

    CarController controller = new CarController(new AppSettings(),  pairingMock.Object, dealerSettingsMock.Object);

    //Act
    var actionResult = await controller.Get(id);
    var actual = actionResult as OkObjectResult;

    //Assert (using FluentAssertions)

    actual.Should().NotBeNull();

    actual.Value.Should().BeOfType<ReturnResult>();

    var actualResult = actual.Value as ReturnResult;

    actualResult.data.Should().BeEquivalentTo(expected);        
}