NancyFx / Nancy

Lightweight, low-ceremony, framework for building HTTP based services on .Net and Mono
http://nancyfx.org
MIT License
7.15k stars 1.46k forks source link

Nancy Testing - prevent autoregistration of IApplicationStartup and IRequestStartup #1793

Closed robertmircea closed 9 years ago

robertmircea commented 9 years ago

I have a NancyFx app which uses the default bootstrapper. This automatically discovers and registers at startup all classes which implement IApplicationStartup interface and IRequestStartup, respectively.

For unit testing my modules I am using Nancy Testing with the ConfigurableBootstrapper which uses the same conventions as the "production" bootstraper thus making the same automatic discovery and registrations of the above classes.

How can I prevent automatic registration of IApplicationStartup and IRequestStartup assignable classes in unit testing scenarios? For example, I have a NewRelic app startup logic which I don't want to use in my unit tests.

Crisfole commented 9 years ago

:+1: I was just coming here to register this bug.

thecodejunkie commented 9 years ago

I see this as a multi-facetted thing. It's not as trivial as just being able to prevent auto-registration or not. The reson is that Nancy has it's own implementations of these interfaces and the bootstrapper, indiscriminately, registers them in the container. So what we probably should be doing for the ConfigurableBootstrapper is to prevent auto-regiration of user-defined implementations, while still registering the Nancy ones. On top of that there needs to be helper methods to allow you to register your own types for your test setup.

To make matters worse, there are already methods called ApplicationStartup and RequestStartup on the ConfigurableBootstrapper. These are used to hook into the two "events" and access/modify the pipelines from your test. Ideally the same names would be used to register implementations for IApplicationStartup and IRequestStartup.. alas they're taken, so we need to be more creative here ;)

Something like these

ApplicationStartupTask<T>() where T : IApplicationStartup
ApplicationStartupTasks(params Type[] types)

RequestStartupTask<T>() where T : IApplicationStartup
RequestStartupTasks(params Type[] types)

The way I see it there are three scenarios that needs to be supported

There also needs to be a way to tell it to explicitly not register user-defined implementations all together

DisableAutoApplicationStartupRegistration();
DisableAutoRequestStartupRegistration();

Here are some sample usages


// Disable auto-registration of all user-defined IRequestStartup + only register the IApplicationStartup that is explicitly setup

var browser = new Browser(with =>
{
    with.DisableAutoRequestStartupRegistration();
    with.ApplicationStartupTask<FooApplicationStartup>();
});

// Disable auto-registration of all user-defined IRequestStartup and all user-defined IApplicationStartup

var browser = new Browser(with =>
{
    with.DisableAutoApplicationStartupRegistration();
    with.DisableAutoRequestStartupRegistration();
});

// Only register the IApplicationStartup and IRequestStartup that is explicitly setup

var browser = new Browser(with =>
{
    with.ApplicationStartupTask<FooApplicationStartup>();
    with.RequestStartupTasks(typeof(FooRequestStartup), typeof(BarRequestStartup));
});

Thoughts?

Ping @robertmircea @Crisfole @NancyFx/most-valued-minions @NancyFx/nancy-core-contributors

thecodejunkie commented 9 years ago

Added a pull-request for this #2026

felipeleusin commented 9 years ago

:+1: I even opened an issue for this a while ago #1812 Looking forward to it