【问题标题】:How can I use IConfiguration from my integration tests?如何从我的集成测试中使用 IConfiguration?
【发布时间】:2018-02-26 10:30:56
【问题描述】:

我有一个 API,我正在尝试使用 XUnit 对其进行一些集成测试。这是我的 API 控制器构造函数:

public class MyController : Controller
{
    readonly IMyRepository _myRepository;

    public MyController(IMyRepository myRepository)
    {
        _myRepository = myRepository;
    }

    public async Task<IActionResult> GetUser(Guid userId)
    {
        try
        {
            return Ok(await _my.GetUser(userId));
        }
        catch (Exception ex)
        {
            return StatusCode(500, "An error occurred while handling your request.");
        }
    }
}

我的 API 控制器正在使用此存储库:

public class MyRepository : IMyRepository
{
    private string _connectionString;

    public MyRepository(IConfiguration config)
    {
        _connectionString = config.GetConnectionString("DefaultConnection");
    }


    public async Task<User> GetUser(Guid userId)
    {
        using (SqlConnection con = new SqlConnection(connectionString))
        {
            // call stored proc
        }
    }
}

存储库使用连接字符串在我的方法中进行一些数据库调用。这在我调用我的 API 方法时有效,因为配置是在我的 API 应用程序的 Startup 类中设置的。

但我不确定如何将带有连接字符串的配置对象从我的集成测试方法传递到我的存储库:

public async Task GetUserShouldReturnOk()
{
    var userId = new Guid();
    var configuration = // ????

    var controller = new MyController(
        new MyRepository(configuration));

    var result = await controller.GetUser(userId);

    Assert.IsType<OkResult>(result);
}

我尝试使用我的连接字符串信息将 json 设置文件添加到我的 XUnit 项目中,然后尝试像我的 Startup 类一样构建它,但我收到一个错误,因为它正在我的测试项目中寻找 json 文件\bin\Debug\netcoreapp2.0\ 目录,所以我不确定如何将基本路径指向正确的位置:

var configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json")
    .Build();

有没有合适的方法来做到这一点?

【问题讨论】:

  • 存储库会连接到实际数据源还是会用假数据模拟源?只需模拟配置接口并将其注入依赖类。没有足够的信息来提供比刚才建议的更好的信息。
  • 您能否展示如何使用连接字符串。我认为当前的存储库实现可能存在一些设计问题。
  • @Nkosi - 它连接到一个实际的数据源。我添加了代码,以便您可以查看存储库中如何使用连接字符串。
  • 在考虑了我最初的建议之后,为什么不将配置生成器的基本路径设置为 json 文件所在的路径?
  • 您还应该查看有关该主题的官方文档Integration testing in ASP.NET Core

标签: c# unit-testing asp.net-core integration-testing xunit


【解决方案1】:

我认为最好在你的测试项目中使用依赖注入;以备将来使用。

在您的测试项目中:

  1. 将新的 appsettings.json 文件添加到您的测试项目中,其中包含您需要的所有配置。
  2. 安装包:Microsoft.Extensions.DependencyInjection。
  3. 为测试设置创建一个类;例如 TestSetup.cs。

    public class TestSetup
    {
        public TestSetup()
        {
            var serviceCollection = new ServiceCollection();
            var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile(
                     path: "appsettings.json",
                     optional: false,
                     reloadOnChange: true)
               .Build();
            serviceCollection.AddSingleton<IConfiguration>(configuration);
            serviceCollection.AddTransient<MyController, MyController>();
    
            ServiceProvider = serviceCollection.BuildServiceProvider();
        }
    
        public ServiceProvider ServiceProvider { get; private set; }
    }
    
  4. 在你的测试课上;我正在使用 Xunit

    public class MyControllerTest: IClassFixture<TestSetup>
    {
        private ServiceProvider _serviceProvider;
        private MyController _myController;
    
        public MyControllerTest(TestSetup testSetup)
        {
           _serviceProvider = testSetup.ServiceProvider;
           _myController = _serviceProvider.GetService<MyController>();
        }
    
        [Fact]
        public async Task GetUserShouldReturnOk()
        {
            var result = await _myController.GetUser(userId);
            Assert.IsType<OkResult>(result);
        }
    
    }
    

【讨论】:

    【解决方案2】:

    appsettings.json 文件就在我的测试项目根目录中,你知道获取当前项目路径的简单方法,这样我就不必对该值进行硬编码

    将文件的Build Action属性设置为Content,这样它将复制到输出目录,以便在测试时将其移动到bin,然后您可以将原始配置代码与.SetBasePath(Directory.GetCurrentDirectory())一起使用

    public async Task GetUserShouldReturnOk() {
        var userId = new Guid();
        var configuration = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json")
                .Build();
    
        var controller = new MyController(
            new MyRepository(configuration));
    
        var result = await controller.GetUser(userId);
    
        Assert.IsType<OkResult>(result);
    }
    

    【讨论】:

    • 感谢@Nkosi 的回答。 appsettings.json 文件就在我的测试项目根目录中,你知道获取当前项目路径的简单方法,这样我就不必硬编码那个值了吗?
    • @Steven,您可以更改文件的属性以复制到输出目录,以便在测试时将其移动到 bin,然后您可以使用带有 .SetBasePath(Directory.GetCurrentDirectory()) 的原始配置代码跨度>
    猜你喜欢
    • 1970-01-01
    • 2019-03-27
    • 2011-04-24
    • 2023-03-26
    • 2020-12-02
    • 1970-01-01
    • 2015-05-15
    • 2022-08-10
    • 1970-01-01
    相关资源
    最近更新 更多