Testing Ninject project installed via Nuget - WebActivate behavior - nunit

I am trying to create a NUnit test for a project that uses Ninject. The Ninject was installed via Nuget, so the Configuration clas looks similar to this simplified version:
[assembly: WebActivator.PreApplicationStartMethod(typeof(NinjectMVC3), "Start")]
[assembly: WebActivator.ApplicationShutdownMethodAttribute(typeof(NinjectMVC3), "Stop")]
public static class NinjectMVC3
{
private static readonly Bootstrapper Bootstrapper = new Bootstrapper();
private static IKernel _kernel;
public static void Start()
{
DynamicModuleUtility.RegisterModule(typeof(OnePerRequestModule));
DynamicModuleUtility.RegisterModule(typeof(HttpApplicationInitializationModule));
Bootstrapper.Initialize(CreateKernel);
}
public static void Stop()
{
Bootstrapper.ShutDown();
}
}
I want those methods to be called in my startup test class. I tried:
[TestFixture]
public class TestBase
{
[SetUp]
public void Setup()
{
NinjectMVC3.Startup();
}
[TearDown]
public void TearDown()
{
NinjectMVC3.TearDown();
}
}
It will not work because I am trying to manually call methods that are managed by WebActivator. So I am looking for a way to instruct WebActivator to call those methods in a 'right time'. Let me remind you that there are two project that I am dealing with, one is a MVC Web Project (and it uses WebActivator for Ninject), and the other one is a Test project for my MVC Web Project. I tried to call WebActivator by changing implementation of my Setup method:
[SetUp]
public void Setup()
{
WebActivator.ActivationManager.Run();
}
It doesn't work. As far As I understand underneath this call WebActivator should do something similar to:
foreach (var assemblyFile in Directory.GetFiles(HttpRuntime.BinDirectory, "*.dll")) {
var assembly = Assembly.LoadFrom(assemblyFile);
foreach (PreApplicationStartMethodAttribute preStartAttrib in assembly.GetCustomAttributes(
typeof(PreApplicationStartMethodAttribute),
inherit: false)) {
preStartAttrib.InvokeMethod();
}
}
So I guess that it is unable to find an assembly. So the question is - how can I order WebActivator to scan thru some additional assembly and fire some methods in a 'right time'. Or maybe I am mislead here, and in order to test my Ninject project I should take a different approach?
I am able to test my solutions w/o WebActivator, but because it is widely used recently, I am keen to learn how to deal with it and force it to do things that I want.

I would avoid using WebActivator from your test project as it will not play well outside of asp.net.
If you want to test the setup of your Ninject kernel than i would make the CreateKernel() method public and call that from your Setup() method.
public static IKernel CreateKernel()
...
[SetUp]
public void Setup()
{
NinjectMVC3.CreateKernel();
}

Unfortunately by default WebActivator looks for a "*.dll" in a c:\tmp... directory, and due to that it is unable to find project libriaries that are included to the solution.
I ended up geting the source code and adding a following code to the ActivationManager class:
public static void AddAssembly(Assembly assembly)
{
if (_assemblies == null)
{
_assemblies = new List<Assembly>();
}
_assemblies.Add(assembly);
}
And in test class:
private const int PreStartInitStage_DuringPreStartInit = 1;
[SetUp]
public void Setup(){
WebActivator.ActivationManager.AddAssembly(Assembly.GetAssembly(typeof(NinjectMVC3)));
typeof(BuildManager).GetProperty("PreStartInitStage", BindingFlags.NonPublic | BindingFlags.Static).SetValue(null, PreStartInitStage_DuringPreStartInit, null);
WebActivator.ActivationManager.RunPreStartMethods();
Kernel = NinjectMVC3.GetKernel();
}
This is ugly code, and I hope to see one day a better approach.

Related

How to log queries using Entity Framework 7?

I am using Entity Framework 7 on the nightly build channel (right now I'm using version EntityFramework.7.0.0-beta2-11524) and I'm trying to log the queries that EF generates just out of curiosity.
I'm writing a simple console program, I tried using the same logging technic that EF6 uses, but DbContext.Database.Logis not available on Entity Framework 7. Is there a way to log or just take a peek at the SQL generated by EF7?
For those using EF7 none of the above worked for me. But this is how i got it working. (from #avi cherry's comment)
In your Startup.cs you proably have a Configure method with a bunch of configurations in it. It should look like below (in addition to your stuff).
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
//this is the magic line
loggerFactory.AddDebug(LogLevel.Debug); // formerly LogLevel.Verbose
//your other stuff
}
You can log to the console using this code, I am sure it will be wrapped in a simpler api later:
using System;
using Microsoft.Data.Entity.Infrastructure;
using Microsoft.Data.Entity.Utilities;
using Microsoft.Framework.Logging;
public static class SqlCeDbContextExtensions
{
public static void LogToConsole(this DbContext context)
{
var loggerFactory = ((IAccessor<IServiceProvider>)context).GetService<ILoggerFactory>();
loggerFactory.AddProvider(new DbLoggerProvider());
}
}
And the DbLoggerProvider is implemented here: https://github.com/ErikEJ/EntityFramework7.SqlServerCompact/tree/master/src/Provider40/Extensions/Logging
If you are using MS SQL Server, one way I have used in the past is to make use of the SQL Server Profiler and capture all interaction with the SQL Server, this captures the exact SQL submitted and can be cut n pasted into the SQL Server Management Studio for further review/analysis.
I know this does not directly answer your question on Entity Framework, but I have found this generic approach very useful for any language/tools.
One tip is in the Trace Properties when setting up a new trace, I have found it useful to adjust the default selection of events in the Events Selection tab. Mostly I turn off the Audit Login/Logout unless specifically tracking such an issue.
I struggled with all the above answers as the EF bits kept changing, so the code wouldn't compile. As of today (19Feb2016) with EF7.0.0-rc1-final (Prerelease) and SQLite, here's what works for me:
From the EF7 documentation:
using System;
using System.IO;
using Microsoft.Extensions.Logging;
namespace EFLogging
{
public class EFLoggerProvider : ILoggerProvider
{
public ILogger CreateLogger(string categoryName)
{
return new EFLogger();
}
public void Dispose()
{
// N/A
}
private class EFLogger : ILogger
{
public IDisposable BeginScopeImpl(object state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return true;
}
public void Log(LogLevel logLevel, int eventId, object state, Exception exception, Func<object, Exception, string> formatter)
{
File.AppendAllText(#".\EF.LOG", formatter(state, exception));
Console.WriteLine(formatter(state, exception));
}
}
}
}
Using some ideas above and the EF7 Docs:
using System;
using Microsoft.Data.Entity;
using Microsoft.Data.Entity.Infrastructure;
using Microsoft.Extensions.DependencyInjection; // Add this to EF7 docs code
using Microsoft.Extensions.Logging;
namespace DataAccessLayer
{
public static class DbContextExtensions
{
public static void LogToConsole(this DbContext context)
{
var serviceProvider = context.GetInfrastructure<IServiceProvider>();
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
loggerFactory.AddProvider(new EFLoggerProvider(logLevel));
}
}
}
EDIT: #jnm2 pointed out if you add "using Microsoft.Extensions.DependencyInjection", the EF7 docs ARE correct. Thanks!
And finally, in my App.OnStartup method:
using (var db = new MyDbContext())
{
db.LogToConsole();
}
This code will create a log file and also output logging info to the Visual Studio output window. I hope this helps -- I'm sure in a few weeks, the bits will change again.
With the latest version of EF7-beta8, Anthony's answer need a little tweaking. Here's what I did to get it to work.
internal static class DbContextExtensions
{
public static void LogToConsole(this DbContext context)
{
var loggerFactory = context.GetService<ILoggerFactory>();
loggerFactory.AddConsole(LogLevel.Verbose);
}
}
I think I figured this out. With the current EF7 bits, ILoggerFactory is registered with the dependency injection container which EF is using. You can get a reference to the container, which is an IServiceProvider, via the ScopedServiceProvider property of DbContext when it is cast to IDbContextServices. From there, you can get the ILoggerFactory and configure it using the AddToConsole extension method from the Microsoft.Framework.Logging.Console NuGet package.
public static void LogToConsole(this DbContext context)
{
// IServiceProvider represents registered DI container
IServiceProvider contextServices = ((IDbContextServices)context).ScopedServiceProvider;
// Get the registered ILoggerFactory from the DI container
var loggerFactory = contextServices.GetRequiredService<ILoggerFactory>();
// Add a logging provider with a console trace listener
loggerFactory.AddConsole(LogLevel.Verbose);
}
Here is a gist I created for this snippet: https://gist.github.com/tonysneed/4cac4f4dae2b22e45ec4
This worked for me with EF7 rc2-16485:
"EntityFramework.MicrosoftSqlServer": "7.0.0-rc2-16485",
"Microsoft.Extensions.Logging.Console": "1.0.0-rc2-15888",
public static class DbContextExtensions
{
public static void LogToConsole(this DbContext context)
{
var contextServices = ((IInfrastructure<IServiceProvider>) context).Instance;
var loggerFactory = contextServices.GetRequiredService<ILoggerFactory>();
loggerFactory.AddConsole(LogLevel.Verbose);
}
}
As an alternative to the above answers, I found this answer by far the easiest solution for me to reason about:
private readonly ILoggerFactory loggerFactory;
// Using dependency injection
public FooContext(ILoggerFactory loggerFactor) {
this.loggerFactory = loggerFactory;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) {
optionsBuilder.UseLoggerFactory(loggerFactory); // Register logger in context
}
With ASP.NET Core 2.0 you get SQL logging automatically. No need to do anything extra.
For those who just want SQL queries to be logged (using Entity Framework Core with .NET Core 2.0 or above), use the following code in your DbContext class:
public static readonly LoggerFactory MyLoggerFactory
= new LoggerFactory(new[]
{
new ConsoleLoggerProvider((category, level)
=> category == DbLoggerCategory.Database.Command.Name
&& level == LogLevel.Information, true)
});
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(MyLoggerFactory) // Warning: Do not create a new ILoggerFactory instance each time
.UseSqlServer(
#"Server=(localdb)\mssqllocaldb;Database=EFLogging;Trusted_Connection=True;ConnectRetryCount=0");
Reference: https://learn.microsoft.com/en-us/ef/core/miscellaneous/logging

Testing multiple interface implementations with same tests - JUnit4

I want to run the same JUnit tests for different interface implementations. I found a nice solution with the #Parameter option:
public class InterfaceTest{
MyInterface interface;
public InterfaceTest(MyInterface interface) {
this.interface = interface;
}
#Parameters
public static Collection<Object[]> getParameters()
{
return Arrays.asList(new Object[][] {
{ new GoodInterfaceImpl() },
{ new AnotherInterfaceImpl() }
});
}
}
This test would be run twice, first with the GoodInterfaceImpl then with the AnotherInterfaceImpl class. But the problem is I need for most of the testcases a new object. A simplified example:
#Test
public void isEmptyTest(){
assertTrue(interface.isEmpty());
}
#Test
public void insertTest(){
interface.insert(new Object());
assertFalse(interface.isEmpty());
}
If the isEmptyTest is run after the insertTest it fails.
Is there an option to run automatically each testcase with a new instance of an implementation?
BTW: Implementing a clear() or reset()-method for the interface is not really an options since I would not need it in productive code.
Here is another approach with the Template Method pattern:
The interface-oriented tests go into the base class:
public abstract class MyInterfaceTest {
private MyInterface myInterface;
protected abstract MyInterface makeContractSubject();
#Before
public void setUp() {
myInterface = makeContractSubject();
}
#Test
public void isEmptyTest(){
assertTrue(myInterface.isEmpty());
}
#Test
public void insertTest(){
myInterface.insert(new Object());
assertFalse(myInterface.isEmpty());
}
}
For each concrete class, define a concrete test class:
public class GoodInterfaceImplTest extends MyInterfaceTest {
#Override
protected MyInterface makeContractSubject() {
// initialize new GoodInterfaceImpl
// insert proper stubs
return ...;
}
#Test
public void additionalImplementationSpecificStuff() {
...
}
}
A slight advantage over #Parameter is that you get the name of the concrete test class reported when a test fails, so you know right away which implementation failed.
Btw, in order for this approach to work at all, the interface must be designed in a way which allows testing by the interface methods only. This implies state-based testing -- you cannot verify mocks in the base test class. If you need to verify mocks in implementation-specific tests, these tests must go into the concrete test classes.
Create a factory interface and implementations, possibly only in your test hierarchy if you don't need such a thing in production, and make getParameters() return a list of factories.
Then you can invoke the factory in a #Before annotated method to get a new instance of your actual class under test for each test method run.
Just in case somebody reaches here(like I did), looking for testing multiple implementations of the same interface in .net you could see one of the approaches that I was using in one of the projects here
Below is what we are following in short
The same test project dll is run twice using vstest.console, by setting an environment variable. Inside the test, (either in the assembly initialize or test initialize) register the appropriate implementations into a IoC container, based on the environment variable value.
In Junit 5 you could do:
#ParameterizedTest
#MethodSource("myInterfaceProvider")
void test(MyInterface myInterface) {}
static Stream<MyInterface> myInterfaceProvider() {
return Stream.of(new ImplA(), new ImplB());
}
interface MyInterface {}
static class ImplA implements MyInterface {}
static class ImplB implements MyInterface {}

Using MS Test ClassInitialize() and TestInitialize() in VS2010 as opposed to NUnit

I've used NUnit with VS2008, and now am adapting to MSTest on VS2010. I used to be able to create an object in TestSetup() and dispose of it in TestCleanup(), and have the object created each time a test method was run in NUnit, preventing me from duplicating the code in each test method.
Is this not possible with MSTest? The examples I am finding using the ClassInitialize and ClassCleanup and TestInitialize and TestCleanup attributes only show how to write to the console. None show any more detailed use of these attributes.
Here is a simple example using TestInitialize and TestCleanup.
[TestClass]
public class UnitTest1
{
private NorthwindEntities context;
[TestInitialize]
public void TestInitialize()
{
this.context = new NorthwindEntities();
}
[TestMethod]
public void TestMethod1()
{
Assert.AreEqual(92, this.context.Customers.Count());
}
[TestCleanup]
public void TestCleanup()
{
this.context.Dispose();
}
}

How To Centrally Initialize an IOC Container in MbUnit?

We currently have a suite of integration tests that run via MbUnit test suites. We are in the process of refactoring much of the code to use an IOC framework (StructureMap).
I'd like to configure/initialize the container ONCE when the MBUnit test runner fires up, using the same registry code that we use in production.
Is there a way of achieving this in MbUnit?
(EDIT) The version of MbUnit is 2.4.197.
Found it. The AssemblyCleanup attribute.
http://www.testingreflections.com/node/view/639
I understand that you want to spin up only one container for your entire test run and have it be the container used across test suite execution. The MBUnit docs make it look like you might be able to use a TestSuiteFixture and TestSuiteFixtureSetup to accomplish about what you want.
I wanted to speak from the point of view of a StructureMap user and Test Driven Developer.
We rarely use containers in our test suites unless we are explicitly testing pulling things out of the container. When this is necessary I use the an abstract test base class below (warning we use NUnit):
[TestFixture]
public abstract class with_container
{
protected IContainer Container;
[TestFixtureSetUp]
public void beforeAll()
{
Container = new ServiceBootstraper().GetContainer();
Container.AssertConfigurationIsValid();
}
}
public class Bootstraper
{
public Bootstraper()
{
ObjectFactory.Initialize(x =>
{
//register stuff here
});
}
public IContainer GetContainer()
{
return ObjectFactory.Container;
}}
I would recommend for normal tests that you skip the normal container and just use the automocking container included with StructureMap. Here is another handy abstract test base class we use.
public abstract class Context<T> where T : class
{
[SetUp]
public void Setup()
{
_services = new RhinoAutoMocker<T>(MockMode.AAA);
OverrideMocks();
_cut = _services.ClassUnderTest;
Given();
}
public RhinoAutoMocker<T> _services { get; private set; }
public T _cut { get; private set; }
public SERVICE MockFor<SERVICE>() where SERVICE : class
{
return _services.Get<SERVICE>();
}
public SERVICE Override<SERVICE>(SERVICE with) where SERVICE : class
{
_services.Inject(with);
return with;
}
public virtual void Given()
{
}
public virtual void OverrideMocks()
{
}
}
and here is a basic test using this context tester:
[TestFixture]
public class communication_publisher : Context<CommunicationPublisher>
{
[Test]
public void should_send_published_message_to_endpoint_retrieved_from_the_factory()
{
var message = ObjectMother.ValidOutgoingCommunicationMessage();
_cut.Publish(message);
MockFor<IEndpoint>().AssertWasCalled(a => a.Send(message));
}
}
Sorry if this is not exactly what you wanted. Just these techniques work very well for us and I wanted to share.

SetUp in derived classes with NUnit?

If I have the following code:
[TestFixture]
public class MyBaseTest
{
protected ISessionManager _sessionManager;
[SetUp]
public void SetUp() { /* some code that initializes _sessionManager */ }
}
[TestFixture]
public class MyDerivedTest : MyBaseTest
{
IBlogRepository _repository;
[SetUp]
public void SetUp() { /* some code that initializes _repository */ }
[Test]
public void BlogRepository_TestGoesHere() { /* some tests */ }
}
...NUnit doesn't call the base SetUp routine. This is expected, and I don't have a problem with it in itself. I can get the derived SetUp to call the base SetUp first, like this:
[TestFixture]
public class MyDerivedTest : MyBaseTest
{
IBlogRepository _repository;
[SetUp]
public new void SetUp()
{
base.SetUp();
/* some code that initializes _repository */
}
This is ugly. If it was a constructor, I wouldn't have to.
I could use the "template method" pattern, and have the following:
public void MyBaseTest
{
abstract void SetUp();
[SetUp]
public void BaseSetUp()
{
/* base initialization */
SetUp(); // virtual call
}
}
I'm not particularly fond of this, either.
What do you do when their test classes need SetUp, and they're derived from another class that also needs SetUp?
You have to call the method directly.
[SetUp]
public void DerivedSetUp()
{
base.BaseSetUp();
// Do something else
}
Edit: I haven't tried it, but perhaps a partial method might work too. I'd prefer to do the above though.
Edit2: I've just tried using partial methods. It didn't work. Even if it did, I think it's still going to be easier to call the base class.
You have the base class explicitly. Given that NUnit uses the [Setup] attribute to mark up test setup, I tink this is "the right thing" to do for NUnit, because it follows the usual language rules.
Sure, NUnit could search the base classes, and call their Setup functions automagically, but I think this would be rather surprising for most people.
There is however at least one unit testing framework that uses constructors for setup: xUnit.Net. Here, the base class setup is called automatically, because this is how constructors in C# behave.
(Note, though, that xUnit.Net recommends again using test setup.)
It looks like you want the setup to be run once before any testing starts, not once before each test is run. The annotation [SetUp] makes the method run once before each test in your fixture is run. [SetUp] is not inherited.
The annotation you want to use is [TestFixtureSetUp] which is run only once, before any of the tests in a fixture are run. This is inherited in the way that you would expect. :)
See the TextFixtureSetUp docs
An approach that I use that I learned in the TDD FireStarter in Tampa was to have the setup method in the base class and then to have a virtual method in the base class called observe. This method is then called in the base class at the end of the setup method.
Then what you do is in the new class that derives from the base class you will override the observe method. The trick in this scenario is you want to execute the Setup method of the base class and the child class does not have a Setup method. The reason for this is the code that you have in the observe method are only those additional things you need for the child test class.
This approach works well for me, but one gotcha is that the test runner will want to execute the base class tests, so what I do to get around that is to move the Tests from the base class into a new class that derives from the base if I have any.
The following works in MbUnit. It may work in NUnit as well.
[TestFixture]
public abstract class Base {
[SetUp]
public virtual void SetUp() {
//Some stuff.
}
}
public class Derived : Base {
public override void SetUp() {
base.SetUp();
//Some more stuff.
}
[Test]
public virtual void Object_WhenInACertainState_WhenAMethodIsCalled_Throws() {
//Create and set state on the object.
//Call the method.
//Assert the method threw.
}
}