C# Unit-test not running when constructor class exist - c#

This is a simple unit Test class with test method called 'TestMethod1()' . when i write ctor inside it, unit test doesn't run anymore. but without ctor test case work as well.
public class OrderTests
{
public OrderTests (int value)
{ }
public void TestMethod1()
{
Xunit.Assert.Equal(7, 7);
}
}
Thanks a lot.

You need to add the Fact attribute to the test so that is recognised as a test and not just a method e.g.:
[Fact]
public void TestMethod1()
{
Xunit.Assert.Equal(7, 7);
}

Related

"Run a method only if a condition is satisfied" pattern

I have a method
using Microsoft.VisualStudio.TestTools.UnitTesting; // using visual studio's test framework
[TestMethod]
public void ATestMethod()
{
// stuff
}
from a public class ATestClass. This test class runs two types of tests :
tests requiring that a certain software is installed on the machine running the test
tests that can run free
To handle this, I added a public class BaseTestClass from which I made ATestClass derive, and in ATestClass I added a :
public bool isTheSoftwareInstalledOnTheMachine()
{
// stuff
}
and I "decorated" all internal scopes of tests from ATestClass as follows :
[TestMethod]
public void ATestMethod()
{
if (isTheSoftwareInstalledOnTheMachine())
{
// stuff
}
}
I find this horrible. I would rather like to be able to write something like :
[TestMethod]
[RunIfTheSoftwareInstalledOnTheMachine]
public void ATestMethod()
{
// stuff
}
but I don't know if one is allowed to define "custom" [characterizer]'s. (I don't even know the right word for them.) If it is, would that be the best design ? (I heard about the decorator pattern, but I don't know if I could make it generic enough in my context, because I would potentially need to use the condition for many other test classes.) Anyway, how would I proceed with characterizer's ?
I know you're using VS test framework but if you can change to NUnit you can accomplish what you want.
Test case:
using NUnit.Framework;
[TestFixture]
public class MyAppTests
{
[Test]
[RunIfTheSoftwareInstalledOnTheMachine]
public void ATestMethod()
{
// Executes if custom attribute is true, otherwise test case is ignored
}
}
Custom attribute:
using NUnit.Framework;
using NUnit.Framework.Interfaces;
public class TestHelper
{
public static bool IsTheSoftwareInstalledOnTheMachine()
{
// Return state of software
return true;
}
}
public class RunIfTheSoftwareInstalledOnTheMachineAttribute : Attribute, ITestAction
{
public ActionTargets Targets { get; private set; }
public void AfterTest(ITest test) {}
public void BeforeTest(ITest test)
{
if (!TestHelper.IsTheSoftwareInstalledOnTheMachine())
{
Assert.Ignore("Omitting {0}. Software is not installed on machine.", test.Name);
}
}
}
If you define your own attribute you surerly have to check for its existance on your own. You can´t expect your framework to guess what the attribute is for.
But I suppose you don´t even need an attribute to do this. You can simply ignore the test by putting the logic inside the test-method anyway:
[Test]
public void MyTest()
{
if(!RunIfTheSoftwareInstalledOnTheMachine)
Assert.Ignore("Test not run because no software was installed");
// your actual test-code
}
Another approach is to use the CategoryAttribute provided by NUnit, with which you can run only those tests that fall within your provided category:
[Test]
[Category("SoftwareInstalled")]
public void MyTest() { /* ... */ }
EDIT: You could also use the TestCaseAttribute with a specific method that returns a TestCase when the condition is met:
[TestCaseSource("ProvideTestcases")]
public void MyTest() { /* ... */ }
private static IEnumerable<TestCaseData> ProvideTestcases()
{
if(RunIfTheSoftwareInstalledOnTheMachine)
yield return new TestCaseData();
}
If the codition is not met no testcase is generated at all.
If the software being installed on the machine is a requirement for any of the tests to pass and any one test failing means the whole suite fails then why bother checking in multiple tests if the software is installed? Just write a single test to fail if the software is not installed and throw a useful exception. Something like:
[Test]
public void EnsureImportantSoftwareIsInstalled()
{
if(!importantSoftwareIsInstalled)
{
Assert.Fail($"Software X must be installed for the tests in {nameof(MyTestClass)} to run, please install it");
}
}
For Nunit 2.6, a slight variation of the HimBromBeere's answer works well for me. The test case is displayed as ignored.
[TestCaseSource("ProvideTestcases")]
public void MyTest() { /* ... */ }
private static IEnumerable<TestCaseData> ProvideTestcases()
{
if(RunIfTheSoftwareInstalledOnTheMachine)
yield return new TestCaseData().Ignore();
}

how to skip constructor call from unit test?

I am executing unit test for one of class method "Execute", but don't want to execute class constructor code.
Is there any way to skip constructor code call from the unit test execution?
Class Code,
public class DemoCls
{
public DemoCls()
{
string ConfigFolderPath = Path.Combine(Environment.CurrentDirectory, #"\Config");
//string dataFolder = #"C:\Data1";
foreach (string X in Directory.EnumerateFiles(ConfigFolderPath, "test" + "*.xml"))
{
}
}
public void Execute()
{
}
}
Unit Test Code,
[TestClass()]
public class DemoClsTests
{
[TestMethod()]
public void ExecuteTest()
{
var X = new DemoCls();
X.Execute();
}
}
Rewrite the class, one of two ways:
Pass the information into the constructor using an interface (which can be mocked in unit-tests)
public interface IConfigFiles
{
List<string> Files { get; set; }
}
public DemoCls(IConfigFiles files)
{
}
Remove configuration code from the constructor, and put it in a different function instead.
public DemoCls()
{
// does nothing
}
public void Setup()
{
string ConfigFolderPath = Path.Combine(Environment.CurrentDirectory, #"\Config");
//...
}
Interfaces are better for unit-testing.
"Is there any way to skip constructor code call from the unit test execution?"
The answer is: No (for instance methods)
You can use a unit testing frameworks that allows you to mock concrete classes in order to fake a class without an interface, for example i'm using Typemock Isolator and with that i can mock almost any class and decide what is happening with all the class's members and its constructor.
here is a test for the class that you had in your question:
[TestMethod,Isolated]
public void TestMethod()
{
var fake = Isolate.Fake.Instance<DemoCls>(Members.CallOriginal, ConstructorWillBe.Ignored);
fake.Execute();
Isolate.Verify.WasCalledWithAnyArguments(() => fake.Execute());
}
You could wrap you ctor code in the "if" preprocessor directive and execute it conditionally, only during a non-test run.
#define DEBUG
// ...
#if DEBUG
Console.WriteLine("Debug version");
#endif
See
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/preprocessor-directives/preprocessor-if

unit testing a static Main() method in c#

I am trying to write unit tests using visual studio unit testing framework for a static Main method, which is also my entry point to my application. I have my method as follows.
public static void Main()
{
StructureMapBootstrapper.Register();
SetupFilter<Applicant>();
}
and this calls a generic SetupFilter method
private static void SetupFilter<T>() where T : IDataFilterBase, new()
{
var filterName = typeof(T).Name;
if ("StartReceiver".TryGetTrueOrFalseConfigValue(filterName))
{
ObjectFactory.Configure(x => x.For<IDataFilterBase>().Use<T>());
var filter = new T();
filter.StartReceiver();
LogHelper.LogInfo(string.Format("Started {0} Filter Service", filterName));
}
else
{
LogHelper.LogInfo(string.Format("{0} Filter Service NOT started. StartReceiver flag is set to false", filterName));
}
}
First thing that came to my mind is to use MOQ and verify that SetupFilter method was called at least once but the compiler complained on the method being static.
Any idea on how to write a test for this method? How do I set it up using VS-unit testing framework and what do I need to Assert?
In my opinion you have to do a small refactor of your code:
public class MyClass
{
public static void Main()
{
(new MyClass()).run();
}
public void Run()
{
StructureMapBootstrapper.Register();
SetupFilter<Applicant>();
}
}
Then you can test normal method instead of static

used in multiple [TestFixture]s

I'm in the process of setting up tests in NUnit and have a newbie question.
Is it possible to have a Test/s that could be used in multiple [TestFixture]s?
So
[Test]ValidateString(string bob)
Could be called in a series of different [TestFixture]?
That doesn't sound like a test to me. Tests are typically parameterless (unless you're using [TestCase]s) and running it within a context of a single fixture would typically be enough -- it either passes once and that's good or it doesn't and it's a broken test.
If you just have a method that does some validation on a string, you could set it up as a static method on some class (e.g. TestHelpers) and call it from whatever tests (in multiple test fixtures) need it.
Here's another idea: inheritance. You can have a base fixture that has all your tests, and then fixtures that inherit from it that set up whatever variables you need. The tests will run for each fixture. I'm not familiar with Selenium RC, but you should be able to adapt the code below to set up whatever variables you need in various fixtures.
[TestFixture]
public class BaseFixtureTests
{
protected IMyClass _myClass;
[TestFixtureSetUp]
public void FixtureSetup()
{
_myClass = ConfigureMyClass();
}
protected virtual IMyClass ConfigureMyClass()
{
// fixtures that inherit from this will set up _myClass here as they see fit.
}
[Test]
public void MyClassTest1()
{
// test something about _myClass;
}
}
[TestFixture]
public class MySpecificFixture1 : BaseFixtureTests
{
protected override IMyClass ConfigureMyClass()
{
return new MySpecificMyClassImplementation();
}
}
public class MySpecificMyClassImplementation : IMyClass
{
//some implementation
}
You can also add extra tests in each fixture as well that don't test common functionality and don't need to be reused across fixtures.
The newer version of NUnit supports generics. This is a great fit if what you are testing doesn’t need to be configured (only created) from your test code. Here is an example copied from http://nunit.net/blogs/:
[TestFixture(typeof(ArrayList))]
[TestFixture(typeof(List<int>))]
public class IList_Tests<TList> where TList : IList, new()
{
private IList list;
[SetUp]
public void CreateList()
{
this.list = new TList();
}
[Test]
public void CanAddToList()
{
list.Add(1); list.Add(2); list.Add(3);
Assert.AreEqual(3, list.Count);
}
}
I’ve also used Anna’s approach of inheritance. One possible refinement to her example (depending on personal preference): Don’t mark the base class as a TestFixture, only the child classes. Each class that you mark as a TestFixture will be displayed as a set of tests in the NUnit client. You will probably never want to run the base class methods directly because the child is providing all of the setup code. If you remove TestFixture from the base class, running invalid tests won’t be an option in the UI. This allows you to run all the tests and see all green… always a nice feeling.
You might be able to achieve what you want with inheritance.
using NUnit.Framework;
namespace ClassLibrary1
{
[TestFixture]
public class TestFixtureBase
{
[SetUp]
public virtual void Setup()
{
// setup code here
}
[Test]
public void CommonTest1()
{
Assert.True(true);
}
[Test]
public void CommonTest2()
{
Assert.False(false);
}
}
public class MyClassTests : TestFixtureBase
{
[SetUp]
public override void Setup()
{
base.Setup();
// additional setup code
}
[Test]
public void MyClassTest1()
{
Assert.True(true);
}
}
}
You can write a method to be called from multiple [Test] methods. But I don't think there is a way to have the same [Test] included in multiple [TestFixture]s.
[TestFixture]
public class TestsOne{
[Test] public void TryOne(){
Helpers.ValidateString("Work?");
}
}
[TestFixture]
public class TestsTwo{
[Test] public void TryTwo(){
Helpers.ValidateString("Work?");
}
}
public static class Helpers{
public static void ValidateString(string s){
Assert.IsNotNull(s);
}
}

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