Init mock database before all tests - c#

I use HttpSelfHostServer to build a RESTful API that uses SQLite database.
I use Moq assembly to mock my database.
Using Nunit I write a TestFixture with SetUp method, which construct MockDatabaseContext. And I have couple tests, that use this MockDatabaseContext.
Now I want to use MockDatabaseContext in all my tests in the test project.
I read article that says:
"...A SetUpFixture outside of any namespace provides SetUp and
TearDown for the entire assembly..."
I moved my SetUp method to another class Init, which is placed in no-namespace, and changed attribute to OneTimeSetUp. That setup's method worked perfectly only one time before running all tests in the assembly as I want.
But the OneTimeSetUp method construct MockDatabaseContext inside not static Init class. How can i pass created MockDatabaseContext to all other tests, which all started after OneTimeSetUp?
[SetUpFixture]
public class Init
{
public Mock<MyDBContext> MockDatabaseContext
[OneTimeSetUp]
public void OneTimeSetUpMethod()
{
MockDatabaseContext = SomeFunctionConstructsMockedContext();
}
}
namespace All.My.Tests
{
[TestFixture]
public class TestFixture1
{
[TestCase]
public void Test1() {/* Here i want to be able using MockDatabaseContext */}
public void Test2() {/* Here i want to be able using MockDatabaseContext */}
public void Test3() {/* Here i want to be able using MockDatabaseContext */}
}
/* Some other fixtures with tests that must have MockDatabaseContext */
}
Thanx

Related

Is it possible to skip the AssemblyInitialize attribute for special tests?

I have two tests: BooUnitTest and BooIntegrationTest.
Within the same testing project I'm holding a method with the AssemblyInitialize attribute decorator:
AssemblyTestsHandler.cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public class AssemblyTestsHandler
{
[AssemblyInitialize]
public static async Task Bootstrap()
{
//Do complex stuff...
}
}
Is it possible to make the Bootstrap method that works only for BooIntegrationTest and not for FooUnitTest?
For example
FooTests.cs:
[TestClass]
public class FooTests
{
[TestMethod]
public async Task FooUnitTest()
{
//Skip Bootstrap()!!
}
}
BooTests.cs
[TestClass]
public class BooTests
{
[TestMethod]
public async Task BooIntegrationTest()
{
//Do Not Skip Bootstrap()!!
}
}
Here is the project structure:
TestingProject
-AssemblyTestsHandler.cs
-BooTests.cs
-FooTests.cs
No, you can't. AssemblyInitialize will be called once per assembly and it will be called before all other methods (AssemblyInitializeAttribute Class):
The method marked with this attribute will be run before methods
marked with the ClassInitializeAttribute, TestInitializeAttribute, and
TestMethodAttribute attributes. Only one method in an assembly may be
decorated with this attribute.
Actually unit tests should be executed in random order:
FooUnitTest1
BooIntegrationTest2
FooUnitTest2
BooIntegrationTest1
in this case any static initialization will affect all other unit-tests.
I think, there are two possibilities:
You can use TestInitialize and TestCleanup attributes for FooTests. But this will affect performance
You can use ClassInitialize for BooTests, but in this case, you have to trigger integration tests separately from unit tests. Integration- and unit tests can be distinguished by TestCathegory attribute.

xUnit.net Class Fixture needs name of test class about to run

I have a project where multiple test classes share a base class fixture.
As expected, the fixture's constructor runs before any test in the test class is run.
Is there a way for this class fixture's constructor to know the name of the test class that is about to run?
Background: My project is not doing unit testing, but rather I'm using xUnit.net to run an alternate type of testing. All the classes and tests will run in order, so a class is guaranteed to run completely before another class tries to run.
Here is an example of what I'd like to be able to do:
using Xunit;
using Xunit.Abstractions;
namespace TestingProject
{
// In my project, the classes are guaranteed to run in order, one after the other. Tests won't randomly execute between classes.
// This fixture is used by multiple test classes. It handles logging test class starts and stops to the db.
public class SharedTestingClassFixture : IDisposable
{
// This will run at the start of every testing class.
public SharedTestingClassFixture()
{
// Need to get name of class that is about to execute, i.e. "TestingClassName"
var nameOfTestingClass = "";
// Log name of class that is about to start to the db BEFORE any tests run.
var logMessage = $"{nameOfTestingClass} class starting";
}
// This will run at the end of every testing class.
public void Dispose()
{
// Log class ending to db after all tests in this class have finished.
}
}
public class TestingClassName : TestClassBase, IDisposable, IClassFixture<SharedTestingClassFixture>
{
// This will run before each individual test.
public TestingClassName(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
{
// At this point, I need to already have written the class name to the db; BEFORE this constructor is called.
// The TestClassBase (not shown) constructor then extracts the test name from testOutputHelper and logs to db.
}
// This will run after each individual test.
public void Dispose()
{
}
[Fact]
public void Test1()
{
// Testing code here
}
[Fact]
public void Test2()
{
// Testing code here
}
}
}

How to run setup code only once in an xUnit.net test

I'm trying to setup my tests using Xunit. I have a requirement to delete all images in a folder start of the tests, and then each method does some image resizing and saves a copy of it's output to the folder. The folder should only be emptied once, and then each method will save their own image into the folder.
When I use IUseFixture<T>, the ClearVisualTestResultFolder function is still being called before every test, so I only end up with one image in the folder.
public class Fixture
{
public void Setup()
{
ImageHelperTest.ClearVisualTestResultFolder();
}
}
public class ImageHelperTest : IUseFixture<EngDev.Test.Fixture>
{
public void SetFixture(EngDev.Test.Fixture data)
{
data.Setup();
}
public static void ClearVisualTestResultFolder()
{
// Logic to clear folder
}
}
If I put the ClearVisualTestResultFolder in the constructor, it is also being called once for every test method. I need this just run once before all test methods are executed, how can I achieve this?
If it matters, I use the ReSharper test runner.
Following the guidance in this xUnit discussion topic, it looks like you need to implement a constructor on the Fixture and also implement IDisposable. Here's a complete sample that behaves the way you want:
using System;
using System.Diagnostics;
using Xunit;
using Xunit.Sdk;
namespace xUnitSample
{
public class SomeFixture : IDisposable
{
public SomeFixture()
{
Console.WriteLine("SomeFixture ctor: This should only be run once");
}
public void SomeMethod()
{
Console.WriteLine("SomeFixture::SomeMethod()");
}
public void Dispose()
{
Console.WriteLine("SomeFixture: Disposing SomeFixture");
}
}
public class TestSample : IUseFixture<SomeFixture>, IDisposable
{
public void SetFixture(SomeFixture data)
{
Console.WriteLine("TestSample::SetFixture(): Calling SomeMethod");
data.SomeMethod();
}
public TestSample()
{
Console.WriteLine("This should be run once before every test " + DateTime.Now.Ticks);
}
[Fact]
public void Test1()
{
Console.WriteLine("This is test one.");
}
[Fact]
public void Test2()
{
Console.WriteLine("This is test two.");
}
public void Dispose()
{
Console.WriteLine("Disposing");
}
}
}
When running this from the console runner, you'll see the following output:
D:\xUnit>xunit.console.clr4.exe test.dll /html foo.htm xUnit.net
console test runner (64-bit .NET 4.0.30319.17929) Copyright (C)
2007-11 Microsoft Corporation.
xunit.dll: Version 1.9.1.1600 Test assembly: test.dll
SomeFixture ctor: This should only be run once
Tests complete: 2 of 2
SomeFixture: Disposing SomeFixture
2 total, 0 failed, 0 skipped, took 0.686 seconds
Then, when you crack open the test output file foo.htm, you'll see the other test output.
The old IUseFixture<T> interface in xUnit.net v1.x has been replaced
by two new interfaces: IClassFixture<T> and ICollectionFixture<T>. In
addition, the mechanism for injecting fixture values into your tests
has changed from property setters to constructor arguments. Class
fixtures are created once and shared amongst all tests in the same
class (much like the old IUseFixture). Collection fixtures work the
same way, except that the single instance is shared amongst all tests
in the same test collection.
NOTE this applies only to xUnit.net v1 - see the accepted answer unless that's your case
IUseFixture<T>.SetFixture gets called once for each test. The Fixture itself is only created once.
In other words, you shouldnt be doing anything in your SetFixture method, but you should be instead be triggering it in the Fixture constructor.
For one-time cleanup, implement an IDisposable.Dispose on the Fixture (it's not required though)
Note that it's a bad idea to be (even potentially) sharing state between tests. Best to use a TemporaryDirectoryFixture like this one.

ClassInitialize attribute in unit test based class not called

I added these method in a TestBase class :
[ClassInitialize]
public static void InitializBeforeAllTests()
{
}
But when I run in Debug an unit test Test1() :
[TestClass]
public class TestMapping : TestBase
{
[TestMethod]
public void Test1()
{
}
The TestBase.InitializBeforeAllTests() method is never called.
Why?
When declaring ClassInitialize attribute on a method, the method has to be static, public, void and should take a single parameter of type TestContext.
If you're having also other method with the AssemblyInitialize attribute on the same unit test, the test will run but will skip on all test methods and will go directly to AssemblyCleanup or just quit.
Try the example on ClassInitialize attribute in MSDN.
You can setup an assembly initialize method in your base class. Not quite the same as ClassInitialize, but it's a viable option. Source:The Workaround mentioned here.
[TestClass]
public abstract class TestBase
{
[AssemblyInitializeAttribute]
public static void Initialize(TestContext context)
{
// put your initialize code here
}
}
You can also add a Cleanup method:
[AssemblyCleanup]
public static void Cleanup()
{
//clean up stuff here
}
for whatever reason, the unit test framework's UnitTestExecuter only allows one ClassInitialize and one ClassCleanup method to be defined per test class... unlike TestInitialize and TestCleanup methods, which get called in both the derived and base test class...
i know this is a very old question, but its the first to popup in google search when looking for a similar problem, anyhow, here is an update for the answer:
[ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)]
public static void YOUR_INIT_METHOD_NAME(TestContext context)
Note: you need MSTest.TestFramework-Version 2.0.0 package or newer for this to work.
The MS link is not working anymore.
Anyway, one way to work around this issue is to simply move your initialization code into the constructor of the base class. This will ensure that it gets called from any descendant classes whenever they are instantiated.
[TestClass]
public class TestBase
{
public TestBase()
{
// Initialization Code
}
}
[TestClass]
public class TestMapping : TestBase
{
[TestMethod]
public void Test1()
{
// At this point the base constructor should have been called
}
}
In my case, I had the[Ignore] attribute applied (test is ran manually)
This caused [AssemblyInitialize] to never be called
If I removed the [Ignore] attribute [AssemblyInitialize] was called as expected.
Oddly, [AssemblyCleanup] is still called with or without the [Ignore] applied to my test

NUnit executes with alternate constructor

I have a class which has some unit tests, but when I am running tests I would like the class to be created with a different constructor. Something like this:
[TestFixture]
public class MyClass
{
public MyClass() { /* set up for production */ }
[TestFixtureConstructor]
public MyClass() { /* set up for testing */ }
[Test]
public void FirstTest()
{
// assert some values
}
}
Is this even possible?
I have considered using a static factory method for creating the class in production (with a private constructor), and a public constructor for the testing framework.
Does anyone have any other solutions?
You don't do this.
You do not have your tests written inside the class that you use in real code; you write your tests external to the classes. I believe most testing suites have the concept of 'Teardown' and the opposite; to set up the test environment for a given execution.
To give a quick example of silky's correct approach:
public class MyClass
{
// ...
}
// In a different assembly:
[TestFixture]
public class TestMyClass
{
[SetUp]
public void SetUp()
{
_myClass = new MyClass();
}
[Test]
public void FooReturnsTrue()
{
Assert.That(_myClass.Foo(), Is.True);
}
// more tests
private MyClass _myClass;
}
If you really really want this you can take a look at TestFixtureSetUp.
Here's the introduction:
This attribute is used inside a TestFixture to provide a single set of functions that are performed once prior to executing any of the tests in the fixture. A TestFixture can have only one TestFixtureSetUp method. If more than one is defined the TestFixture will compile successfully but its tests will not run.
Example:
namespace NUnit.Tests
{
using System;
using NUnit.Framework;
[TestFixture]
public class SuccessTests
{
[TestFixtureSetUp] public void Init()
{ /* ... */ }
[TestFixtureTearDown] public void Dispose()
{ /* ... */ }
[Test] public void Add()
{ /* ... */ }
}
}
But you should use this with care, or else it defeats the purpose of unit test.

Categories

Resources