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.
}
}
Related
I have to write an integration test and I have service like below
public class MyService: IMyService
{
private readonly ISecureStorage secureStorageService;
public MyService(ISecureStorage secureStorageService)
{
this.secureStorageService = secureStorageService;
}
}
How do I create an implementation of ISecureStorage in my test?
ISecureStorage mySecureStorage = new ???????
You can create a test implementation for it or use a mock, since you don't want to test the real SecureStorage class (you can't, really, without a lot of platform specific fuzz).
Option 1: Use the Moq library:
using Moq;
public class MyTests
{
// this conveniently takes care of the mock implementation for you
private Mock<ISecureStorage> _secureStorageMock = new Mock<ISecureStorage>();
[Test]
public void Example()
{
//arrange
var myService = new MyService(_secureStorageMock.object);
//act
myService.DoSomething();
//assert
Assert.IsTrue(myService.Whatever);
// You can also check if a specific method has been called, like below
_secureStorageMock.Verify(s => s.SetAsync(It.IsAny<string>(), It.IsAny<string>());
}
}
Option 2: Create a stub implementation:
public class FakeStorage : ISecureStorage
{
//TODO: implement interface with stub methods that don't actually do anything useful
}
Then use it in your test:
public class MyTests
{
[Test]
public void Example()
{
//arrange
var myService = new MyService(new FakeStorage());
//act
myService.DoSomething();
//assert
Assert.IsTrue(myService.Whatever);
}
}
These are just two ways to do it. More advanced scenarios could involve an inversion of control container. Also, I'm just assuming the use of NUnit here, but the same goes for xUnit, too.
I recommend approach no. 1. It's easier, more powerful and avoids writing a fake or stub implementation.
The NUnit docs describe how to use SetUpFixture so a chunk of code will execute only once. I'm failing to get this working.
I have read Is it possible to have a [OneTimeSetup] for ALL tests? and https://docs.nunit.org/articles/nunit/writing-tests/attributes/setupfixture.html
I have the following structure for my tests
The actual tests (note the inheritence)
namespace net.UiTests
{
[TestFixture]
[NonParallelizable]
internal class SanityTests : TestBase
{
[SetUp]
public void Initialize()
{
//do stuff
}
[TearDown]
public void TestCleanUp()
{
//do stuff
}
[Test]
public void SomeTest()
{
//do stuff
}
}
}
And the base class, which is where the SetUpFixture lives
namespace net.UiTests
{
[NonParallelizable]
[SetUpFixture]
internal class TestBase
{
[OneTimeSetUp]
public static void AssemblyInit()
{
//do stuff
}
[OneTimeTearDown]
public static void AssemblyCleanup()
{
//do stuff
}
}
}
I am unsure why the AssemblyInit() method executes multiple times. The stack trace gives me no clues other than [External Code]
You have made your base class a SetUpFixture, which is causing the problem.
The SetUpFixture runs once before and once after all the fixtures in your UiTests namespace.
But due to inheritance, each TestFixture now "contains" a OneTimeSetUp and a OneTimeTearDown method. Those methods, when found in a TestFixture, are supposed to run once per fixture class and that's what they do.
To solve the problem, you have to stop using the SetUpFixture as a base class.
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 {}
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.
I have a JUnit test that I run on one class, but I recently wrote an emulated version for GWT. Since the specification is the same, I would like to use the same test case, but I want it to run in the GWT environment, which would typically be accomplished by extending GWTTestCase.
I really want to avoid any copy/paste nonsense, because there are likely to be added tests in the future, which I should not be burdened with copying later.
How can I import/inherit my standard unit test to be run as either a regular test case or a GWT test case?
I have found the solution to this problem.
If you extend the original test with GWTTestCase, you can override getModuleName to return null. This tells GWTTestCase to run as a normal pure java test (no translation at all).
You can then extend this test case with one that overrides getModuleName to return a module name, and the same tests will be run with translation.
Basically:
public class RegularTest extends GWTTestCase {
#Override
public String getModuleName() { return null; }
public void testIt() {...}
}
...and the GWT version...
public class GwtTest extends RegularTest {
#Override
public String getModuleName() { return "some.module"; }
}
The downside to this is that it forces you to use JUnit3 style tests, which I find a little annoying, but it beats the alternative.
I think there is no easy way .. But you can extract an interface of your junit test, gwt test case and junit test case implements this interface. You can create a third class for implementation, all test call methods of gwt test case and junit test are delegated to this implementation class.
public interface IRegularTest {
public void testSomething();
public void testSomething2();
}
public class RegularTestImpl implements IRegularTest {
public void testSomething(){
// actual test code
}
public void testSomething2(){
// actual test code
}
}
public class RegularTest extends TestCase implements IRegularTest {
IRegularTest impl = new RegularTestImpl();
public void testSomething(){
impl.testSomething
}
public void testSomething2(){
}
}
public class GwtTest extends TestCase implements IRegularTest {
IRegularTest impl = new RegularTestImpl();
public void testSomething(){
impl.testSomething
}
public void testSomething2(){
}
}