简体   繁体   English

创建一个TestServer并将依赖注入与XUnit和ASP.NET Core 1.0一起使用

[英]Creating a TestServer and using Dependency Injection with XUnit and ASP.NET Core 1.0

I have an ASP.NET Core 1.0 Solution with the following project structure: 我有一个具有以下项目结构的ASP.NET Core 1.0解决方案:

Web App (ASP.NET MVC6) Web应用程序(ASP.NET MVC6)
BusinessLibrary (Class Library Package) BusinessLibrary(类库包)
DataLibrary(Class Library Package) DataLibrary(类库包)
Tests (Class Library Package w/ XUnit ) 测试(带有XUnit的类库程序包)

I am attempting to use Microsoft's new built-in dependency injection all throughout the entire system. 我正在尝试在整个系统中使用Microsoft的新内置依赖项注入。

Here is how everything currently flows from my ASP.NET MVC App all the way down to my Repository layer 这是当前从ASP.NET MVC App一直到存储库层的所有内容的方式

//Startup.cs of MVC Web App
public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    services.AddSingleton(_=> Configuration);

    services.AddTransient<ICustomerService, CustomerService>();
    services.AddTransient<ICustomerRepository, CustomerRepository>();
}

public class CustomersController : Controller
{
    private ICustomerService _service;
    public CustomersController(ICustomerService service)
    {
        _service= service;
    }
}

public class CustomerService : ICustomerService
{
    private ICustomerRepository _repository;
    public PriceProtectionManager(ICustomerRepository repository)
    {
        _repository = repository;
    }
}

public class CustomerRepository : BaseRepository, ICustomerRepository
{
    public CustomerRepository(IConfigurationRoot config) 
    : base(config)
    {
    }
}

public class BaseRepository
{
    private IConfigurationRoot _config;

    public BaseRepository(IConfigurationRoot config)
    {
        _config = config;
    }
}

Now how can I get something similar to work with XUnit project so I can access CustomerService and call the functions? 现在如何获得类似于XUnit项目的东西,以便可以访问CustomerService并调用函数?

Here is what my Fixture class looks like: 这是我的Fixture类的样子:

public class DatabaseFixture : IDisposable
{
    public ICustomerService CustomerService;
    public DatabaseFixture(ICustomerService service)
    {
        CustomerService = service;
    }

    public void Dispose()
    {

    }
}

The problem is that ICustomerService is unable to be resolved... This is probably because I don't have a Startup.cs like my WebApp. 问题是ICustomerService无法解决...这可能是因为我没有像WebApp这样的Startup.cs。 How do I replicate this behavior with the test project? 如何在测试项目中复制这种行为? I don't know where to create my TestServer because if I do it in the fixture it will be too late. 我不知道在哪里创建我的TestServer,因为如果我在夹具中创建它,将为时已晚。

Well, you can provide your own dependencies to your SUT (which is the way you should want it IMHO). 好了,您可以为SUT提供您自己的依赖项(这是您应该对其进行恕我直言的方式)。 I've just answered a similar question here . 我刚刚在这里回答了类似的问题。

If you want to define your connectionstring at one place you could use xUnit's ability to use shared context (fixtures). 如果要在一处定义连接字符串,则可以使用xUnit的使用共享上下文 (夹具)的功能。

Update: Examples incorperating fixtures and DI... 更新:包含固定装置和DI ...

Your testclass should implement IClassFixture and contain for example the following fields and constructor: 您的测试类应实现IClassFixture,并包含例如以下字段和构造函数:

    public class AspnetCoreAndXUnitPrimeShould: IClassFixture<CompositionRootFixture>
{
    private readonly TestServer _server;
    private readonly HttpClient _client;
    private readonly CompositionRootFixture _fixture;

    public AspnetCoreAndXUnitPrimeShould(CompositionRootFixture fixture) 
    {
        // Arrange
        _fixture = fixture;
        _server = new TestServer(TestServer.CreateBuilder(null, app =>
        {
            app.UsePrimeCheckerMiddleware();
        },
            services =>
            {
                services.AddSingleton<IPrimeService, NegativePrimeService>();
                services.AddSingleton<IPrimeCheckerOptions>(_ => new AlternativePrimeCheckerOptions(_fixture.Path));
            }));
        _client = _server.CreateClient();
    }

Notice that AspnetCoreAndXUnitPrimeShould is the name of the testclass in my example. 注意,在我的示例中, AspnetCoreAndXUnitPrimeShould是测试类的名称。 The fixture looks like: 灯具看起来像:

    public class CompositionRootFixture
{
    public string Path { get; }

    public CompositionRootFixture()
    {
        Path = "@/checkprime";
    }
}

This is just a quick adoptation from another example, but you should understand how you can fix your problem now. 这只是另一个示例的快速采用,但是您应该了解如何立即解决问题。 AlternativePrimeCheckerOptions takes a string in the constructor, just like your Configuration class could. AlternativePrimeCheckerOptions在构造函数中采用一个字符串,就像您的Configuration类一样。 And with a fixture you arrange this connectionstring at one place. 并使用夹具将这个连接字符串安排在一个地方。

Update Sample: https://github.com/DannyvanderKraan/ASPNETCoreAndXUnit 更新示例: https : //github.com/DannyvanderKraan/ASPNETCoreAndXUnit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM