xunit IClassFixture without constructor - c#

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
}

Related

Dependency injection with abstract class in .NET Core

I don't know how to use a dependency injection in an abstract class. Let me show you my problem in a simple example:
public abstract class Animal {
public abstract void Move();
public void Sleep()
{
restService.StartSleeping(1000); //how to get this service here?
}
}
public class Cat : Animal
{
public readonly IMotionService _motionService;
public Cat(IMotionService motionService)
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Run();
}
}
public class Bird : Animal
{
public readonly IMotionService _motionService;
public Bird(IMotionService motionService)
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Fly();
}
}
Every animal move in different way so the Move() function is implemented separately in every derived class. As you probably noticed the whole implementation comes from the motionService.
On the other hand all animals sleep in same way, so I want put the Sleep() implementation in a base abstract class to avoid a duplication code, but I can't use my restService with a Sleep implementation because I don't have idea how to inject a service class into an abstract class.
I thought about IServiceProvider but it should be injected too.
You pass it down like this:
public abstract class Animal
{
private readonly IRestService restService;
public Animal( IRestService restService )
{
this.restService = restService;
}
public abstract void Move();
public void Sleep()
{
restService.StartSleeping(1000);
}
}
public class Cat : Animal
{
// vv Should be private!
public readonly IMotionService _motionService;
public Cat(IMotionService motionService,
IRestService restService)
: base(restService) // pass on to base class ctor
{
_motionService = motionService;
}
public override void Move()
{
_motionService.Run();
}
}
// Same in `Bird` class
For reference: Using Constructors (C# Programming Guide)

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)

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

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));
}
}

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();
}
}

why can not create instance from any class out side of constructor?

why i generate instance outside of class. i give inheritance snifC to sinifD i need to create instance sinifC sinifc= new sinifC() in SinifD out side of constructor?
public class sinifC
{
public void method3()
{
Console.WriteLine("Deneme3");
}
}
public class sinifD : sinifC
{
void method4()
{
Console.WriteLine("Deneme4");
}
public sinifD()
{
sinifC sinifc = new sinifC();
sinifc.method3();
}
}
i want to make it below:
public class sinifC
{
public void method3()
{
Console.WriteLine("Deneme3");
}
}
public class sinifD : sinifC
{
void method4()
{
Console.WriteLine("Deneme4");
}
sinifC sinifc = new sinifC();
sinifc.method3();
}
Error: Invalid token '(' in class, struct, or interface member declaration
doesn't
sinifC sinifc = new sinifC();
sinifc.method3();
need to be inside a method?
You seem to want to create an instance of an object and call its method inside the body of the class, but you need to have it happen inside a method.
You don't have to write the code in the constructor, but you do have to write the code in some method. You're currently just writing the code anywhere in your class. If you don't want to have to create an instance of your D class to do this you could create a static method in your D class that creates the instance of the C class (you could even have a static constructor).
The only valid instructions in the body of a class are declarations (optionally including initialization for fields). A method call is not a valid instruction here, it has to be inside a method
You do not need to create an instance of sinifC - you are using inheritace by extending it.
class Program
{
static void Main(string[] args)
{
sinifD s = new sinifD();
// call method3 on sinfiD
s.method3();
}
}
public class sinifC
{
public void method3()
{
Console.WriteLine("Deneme3");
}
}
public class sinifD : sinifC
{
// sinifD inheritrs mehtod3 from sinifD
// method 4 is protected, so only classes in the class hierachy see that method
void method4()
{
Console.WriteLine("Deneme4");
}
}

Categories

Resources