Is it possible to "inherit" tests with xUnit.net? - c#

I have a concrete class called EventManager and a subclass called ScheduledEventManager. I would like ScheduledEventManager to have to pass the same tests as EventManager plus a few additional ones. Is this possible with xUnit.net?
EDIT: I just realized that my case is a little more complicated than this. I'm using nested classes to keep my tests more organized. Example:
public class EventManagerTests
{
public class WhenAnEventIsFired
{
[Fact]
void ItNotifiesSubscribers()
{
// Perform the test
}
}
}
public class ScheduledEventManagerTests
{
// How to I inherit the above tests since they are in nested classes?
}
It seems to me that this is not possible, but maybe one of you geniuses knows something I don't.

Yes You can:
public abstract class EventManagerTests
{
protected IEventManager _ev;
protected EventManagerTests(IEventManager ev)
{
_ev = ev;
}
[Fact]
public void SharedTest()
{
// Perform _ev test
}
}
public class ScheduledEventManagerTests : EventManagerTests
{
public ScheduledEventManagerTests():base(new ScheduledEventManager())
{
}
// It will inherit tests from the base abstract class
}
public class UnScheduledEventManagerTests : EventManagerTests
{
public UnScheduledEventManagerTests():base(new UnScheduledEventManager())
{
}
// It will inherit tests from the base abstract class
}

Create a parameterized test that takes an instance of your base class as the SUT, and invoke the test with an instance of the sub class. Here's a (contrived) example using NUnit, which results in one passing and one failing test:
public class Foo
{
public virtual int DoSomething()
{
return 10;
}
}
public class Bar : Foo
{
public override int DoSomething()
{
return 9;
}
}
[TestFixture]
public class Tests
{
private Foo[] _foos = { new Foo(), new Bar() };
[Test]
[TestCaseSource("_foos")]
public void When_DoSomething_Is_Invoked_Then_A_Power_Of_Ten_Is_Returned(Foo sut)
{
Assert.That(sut.DoSomething() % 10, Is.EqualTo(0));
}
}

Related

CS0175 Use of keyword 'base' is not valid in this context

I am getting CS0175 Use of keyword 'base' is not valid in this context error in my unit test case project.
This is how my code looks:
A class which implements a interface
public interface iUtility
{
void Print();
}
public class Utility: iUtility
{
public void Print()
{
Console.Write("Print");
}
}
A base class which uses the utility class and a derived class
public class BaseCls
{
private iUtility _iUtility;
public BaseCls()
{
_iUtility = new Utility();
}
public BaseCls(iUtility iUtility)
{
_iUtility = iUtility;
}
}
public class DerivedCls : BaseCls
{
public void PrintSomething()
{
Console.Write("Print Something");
}
}
In my unit test project, I am testing derived class and trying to pass the instance of utility class. Why I am doing this may not make sense now but I am planning to use unity framework and use IoC to inject different dependencies.
I am not showing all code for brevity.
Error is happening in unit test project
[TestClass]
public class UnitTest1
{
public void TestInitialize()
{
//I want to pass instance of utility class here
iUtility obj = new Utility();
DerivedCls cls = new DerivedCls(): base(obj);
}
[TestMethod]
public void TestMethod1()
{
}
}
What do I need to do to fix this error? I want to pass the instance of utility class from derived class through constructor.
You need to provide a constructor in your derived class.
public class DerivedCls : BaseCls
{
public DerivedCls(iUtility utility) : base(utility) { }
}
Then construct your DerivedCls instances as you normally would: new DerivedCls(someIUtilityInstance)

xunit IClassFixture without constructor

I have the following simplified pseudocode
class CommonSetup
{
public void CommonSetup()
{
// do stuff once per class
}
public void Foo() { }
}
abstract class BaseTest : IClassFixture<CommonSetup>
{
public void BaseTest(CommonSetup setup)
{
setup.Foo();
}
}
class MyTest : BaseTest
{
// i dont want to have a ctor here
}
I need access to CommonSetup from BaseTest but I don't want MyTest to have a constructor in order to pass CommonSetup through to it because it's pointless boilerplate noise.
Is there a different syntax/mechanism for achieving the same as IClassFixture<> without the need to use constructors to pass the the CommonSetup around?
In my view, it is possible to create a static field to avoid of creation a new object and to share instance across all derived classes.
So let me show an example:
class CommonSetup
{
public CommonSetup()
{
// do stuff once per class
}
public void Foo() { }
}
and:
abstract class BaseTest : IClassFixture<CommonSetup>
{
protected static CommonSetup _commonSetup = new CommonSetup();
public BaseTest()
{
_commonSetup.Foo();
}
}
and your derived classes will not want to have constructor to send parameters for BaseTest class:
class MyTest : BaseTest
{
// There is no need to have constructor to initialize `BaseTest` constructor
}

Skip test method for specific type in generic test class

I'm trying to unit test a part of a project; I'm using NUnit. The targeted unit processes objects of several types, all extending a base type. I've created a generic test class on which I set the desired test types:
[TestFixture(typeof(SomeType))]
[TestFixture(typeof(SomeOtherType))]
class MyTestClass<T> where T : SomeBaseType, new()
{
[Test]
public void DoThisTest()
{
var sut = CreateSut();
var target = CreateTarget();
Assert.IsTrue(sut.Process(target));
}
[Test]
public void DoThatTest()
{
var sut = CreateSut();
var target = CreateInvalidTarget();
Assert.IsFalse(sut.IsValid(target));
}
//...
}
This creates a set of all the tests for each type set using TestFixture. For whatever reason, I have a test which only makes sense in the context of a specific type. This means that I need to either 1) use Assert.Ignore() on all other types or 2) create a different test class just for those "special" test cases.
Is there a way of opting out from a test from outside (attribute?) and specify that that particular test must not be "implemented" in certain contexts? I would like to "combine" 1) & 2) such that all the test cases are in the same file/class but some tests are only rendered/implemented/run for certain values set by TestFixture.
This isn't exactly what you're looking for, but I think it's a pretty close work around. You can specify nested classes within your main test fixture and decorate them with different TestFixture attributes to restrict what's run. It's probably best explained with an example. So, given these data types:
public interface ICompetitor {
string GetFinalPosition();
}
public class Winner : ICompetitor{
public string GetFinalPosition() {
return "Won";
}
}
public class Loser : ICompetitor {
public string GetFinalPosition() {
return "Lost";
}
}
I can define these TestFixtures:
[TestFixture(typeof(Winner))]
[TestFixture(typeof(Loser))]
public class CompetitorTests<T> where T : ICompetitor, new()
{
static private T CreateSut() {
return new T();
}
[Test]
public void EverybodyHasPosition() {
Assert.IsNotNullOrEmpty(CreateSut().GetFinalPosition());
}
[TestFixture(typeof(Winner))]
public class WinnerTests {
[Test]
public void TestWon() {
Assert.AreEqual("Won", CompetitorTests<T>.CreateSut().GetFinalPosition());
}
}
[TestFixture(typeof(Loser))]
public class LoserTests {
[Test]
public void TestLost() {
Assert.AreEqual("Lost", CompetitorTests<T>.CreateSut().GetFinalPosition());
}
}
}
The EverybodyHasPosition test is run twice (once for the Winner and once for the Loser classes). Whereas the TestWon is only run for the Winner class and the TestLost is only run for the Loser class. It's not ideal, because you can only access static members of the outer class, and each fixture is responsible for it's own setup/teardown.
You can work around this though, by using a base class. So, the state sharing version might look more like this (notice that each TestFixture inherits from CompetitorTestsState):
public class CompetitorTestsState<T> where T : ICompetitor, new() {
protected T SUT { get; private set; }
[SetUp]
public void Setup() {
SUT = CreateSut();
}
private T CreateSut() {
return new T();
}
}
[TestFixture(typeof(Winner))]
[TestFixture(typeof(Loser))]
public class CompetitorTests<T> : CompetitorTestsState<T> where T : ICompetitor, new() {
[Test]
public void EverybodyHasPosition() {
Assert.IsNotNullOrEmpty(SUT.GetFinalPosition());
}
[TestFixture(typeof(Winner))]
public class WinnerTests : CompetitorTestsState<T>{
[Test]
public void TestWon() {
Assert.AreEqual("Won", SUT.GetFinalPosition());
}
}
[TestFixture(typeof(Loser))]
public class LoserTests : CompetitorTestsState<T>{
[Test]
public void TestLost() {
Assert.AreEqual("Lost", SUT.GetFinalPosition());
}
}
}

C# Public field that can be updated only from within the class

I have a C# class with a field that needs to be visible from outside the class, but should be changed only from within the class. However, the problem is that the field is updated via a public mutator method, not directly (or by a property):
public class FirstClass
{
public SecondClass TheField {get; private set;}
public FirstClass()
{
TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
TheField.Update(/*parameters*/);
// ...
}
}
public class SecondClass
{
// some fields
public SecondClass() { }
public void Update(/*parameters*/)
{
// do something
}
}
In other words, I would like the method Update() to be accessible only from within FirstClass.
Few possible solutions and the reasons why I'm not safisfied with them:
Change SecondClass with a setter instead of a method. - Wouldn't work because I need to have parameters and a lot of stuff to do.
Make Update() internal instead of public. - Still accessible from within the assembly, not good enough.
Modify SecondClass from the FirstClass, ie. move the method Update() to FirstClass, make it private and expose all needed fields from SecondClass. - doesn't feel very object-oriented.
Call Update() from SecondClass constuctor(s) and make a new instance of SecondClass every time I need to update it. - The performance will suffer because there is some stuff in SecondClass that never changes and I would want to process it every time I call Update().
Is there a way to do this?
A basic implementation of #aquaraga's answer, but using interfaces instead:
public interface ISecond
{
// some properties
}
public class FirstClass
{
private readonly SecondClass _TheField;
public ISecond TheField { get { return _TheField; } }
public FirstClass()
{
_TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
_TheField.Update(/*parameters*/);
// ...
}
private class SecondClass : ISecond
{
// some properties
public void Update(/*parameters*/)
{
// do something
}
}
}
Essentially, expose a public interface that has all the accessible members but no Update method. Employ a private nested class which has an Update method, but otherwise not accessible to calling code and expose it as the interface, not as the class.
Some sample usage:
FirstClass myFirst = ...
myFirst.SomeMethod(); //updates ok!
Console.WriteLine(myFirst.TheField.PropertyA); //can access properties of ISecond
myFirst.TheField.Update(); //compiler error!
One point is that you mention using "some fields"; as an interface you wouldn't be able to have fields but properties instead. I'm not sure if that's a deal breaker or not for you.
EDIT: You mentioned your intent to reuse the SecondClass and minimize code duplication. One quick fix might be to declare some abstract class, a protected Update method, employ an internal constructor (so other assemblies can't inherit from it), then expose the Update call with a minimal implementation:
public abstract class SecondClassBase : ISecond
{
// some properties
internal SecondClassBase()
{
}
protected void Update(/*parameters*/)
{
// do something
}
}
Then in your FirstClass, nothing changes except the nested class:
public class FirstClass
{
private readonly SecondClass _TheField;
public ISecond TheField { get { return _TheField; } }
public FirstClass()
{
_TheField = new SecondClass();
}
public void SomeMethod()
{
// ...
_TheField.Update(/*parameters*/);
// ...
}
private class SecondClass : SecondClassBase
{
public new void Update(/*parameters*/)
{
base.Update(/*parameters*/);
}
}
}
Still some code duplication, but all you need to do now is copy/paste the code; no need to redeclare the properties or the Update logic for each implementation of FirstClass. You could also rename the new Update method to something else to avoid method hiding, but I figured I'd keep the same calling signature you had before.
One way is to make a sub-class called UpdateableSecondClass an inner class to FirstClass.
It would inherit from SecondClass, and have a single method: Update()
Your SecondClass should not have the Update() method at all. You could continue exposing it to the rest of the world:
public SecondClass TheField {get; private set;}
I think that you can use this pattern:
public partial class FirstClass {
partial class ThirdClass: SecondClass {
public void PerformUpdate(/* parameters */) {
base.Update(/* parameters */);
}
}
public void SomeMethod() {
}
public FirstClass() {
}
public SecondClass TheProperty {
get {
return m_TheField;
}
}
ThirdClass m_TheField=new ThirdClass();
}
public partial class SecondClass {
protected void Update(/* parameters */) {
}
public SecondClass() {
}
}
The ThirdClass inherits from SecondClass, but is not exposed. The property exposed as an instance of type SecondClass, but in fact a field of type ThirdClass.
The method SecondClass.Update exposes to derived class only. That you can declare SecondClass public, not nested, but keep the updating of filed private.
What about a Nested Type.
public class FirstClass
{
private SecondClass TheField { get; set; }
public void SomeMethod()
{
TheField.Update( /*parameters*/);
}
private class SecondClass
{
public void Update( /*parameters*/)
{
// do something
}
}
}
Chris Sinclair answer is great,this is just another option
public sealed class FirstClass : SecondClass
{
public FirstClass()
{
}
public void SomeMethod(int j)
{
base.Update(j);
}
}
public abstract class SecondClass
{
public SecondClass() { }
protected void Update(int i)
{
Console.WriteLine(i.ToString());
}
}
this is just for the part of accessing the method through FirstClass

Restricting subclasses from inheriting certain methods of base class

using System;
public class Base
{
public Base()
{
}
public void M1()
{
}
public void M2()
{
}
public void M3()
{
}
}
public class Derived : Base
{
//this class should get only method 1
}
public class SecondDerived : Base
{
//this class should get only method 2 and method3
}
The requirement is : the base class contains the 3 methods M1, M2, M3.
The derived class should inherit only M1 and SecondDerived should inherit only M2 and M3.
How can this be done?
You cannot selectively inherit methods like this. A derived class automatically inherits all public methods of the base class. I suggest you to split the Base class into two classes:
public class Base1
{
public Base1()
{
}
public void M1()
{
}
}
public class Base2
{
public void M2()
{
}
public void M3()
{
}
}
public class First : Base1
public class Second : Base2
You cannot do it in this way. Inheritance implies an "IS A" relationship.
If SecondDerived would not have a M1() then it would not be compatible with a reference to a the class Base.
So maybe you shouldn't be using inheritance for whatever problem you're solving.
It is not possible to do what you want with inheritance.
It seems you have no intention of overriding, you simply want to "inherit" behavior from the base class selectively. You could do this using a "has a" relationship:
public class Base
{
internal Base() {} //mark constructor as internal so it can not be used outside your assembly if necessary
public Foo Mehtod1() {...}
public Foo Mehtod2() {...}
public Foo Mehtod3() {...}
}
Then simply do the following:
class A
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method1() { return this.internalBase.Method1(); }
}
class B
{
private Base internalBase;
public A() { this.internalBase = new Base(); }
public Foo Method2() { return this.internalBase.Method2(); }
public Foo Method3() { return this.internalBase.Method3(); }
}
UPDATE: A possible alternative solution is to make your Base class methods virtual and override them all in your derived classes, throwing NotSupportedExceptions in those methods that you do not want the class to make available. I don't really like this solution but it has the advantage of not loosing the polyphormism inheritance gives you which might be useful if you have some core base functionality which all derived classes will share (in your example you seem to imply they wont).
It is possible by adding Obsolete attribute
public class A
{
public virtual void M1() { }
public void M2() { }
public void M3() { }
}
public class B : A
{
[Obsolete("You can not use this", true)]
public sealed override void M1()
{
}
}
public class C : B
{
public void Test()
{
// Will show error
base.M1();
}
}

Categories

Resources