Say i have this example code:
interface IBase {
int BaseProperty { get; }
}
interface IDerived : IBase {
int DerivedProperty { get; }
}
and i like to write mocks for both interfaces.
Base mock is easy:
class BaseMock : Mock<IBase> {
public int BaseProperty { get; set; } = 42;
public BaseMock() {
SetupGet(o => o.BaseProperty).Returns(BaseProperty);
}
}
but im not sure how to correctly write derived mock:
class DerivedMock : Mock<IDerived> {
public int BaseProperty { get; set; } = 42;
public int DerivedProperty { get; set; } = 73;
public DerivedMock() {
// setups related to IBase
SetupGet(o => o.BaseProperty).Returns(BaseProperty);
// setups related to IDerived
SetupGet(o => o.DerivedProperty).Returns(DerivedProperty);
}
}
this implementation will work as expected, but im forced to copy bassically whole content of BaseMock class here and that is not DRY ...
ideally i would like to inherit DerivedMock from BaseMock, but then setups related to IDerived would not compile (o is IBase and i it to be IDerived)...
I appreciate any kick in the right direction :)
RafaĆ Rutkowski kicked me to right direction and i ended up with this code for anyone else interested:
interface IBase {
int BaseProperty { get; }
}
interface IDerived : IBase {
int DerivedProperty { get; }
}
class BaseMock : Mock<IBase>, IBase {
public int BaseProperty { get; set; } = 42;
public BaseMock() {
SetupAll(this, this);
}
public static void SetupAll<TBase>([NotNull] Mock<TBase> mock, [NotNull] TBase instance)
where TBase : class, IBase {
mock.SetupGet(o => o.BaseProperty).Returns(instance.BaseProperty);
}
}
class DerivedMock : Mock<IDerived>, IDerived {
public int BaseProperty { get; set; } = 42;
public int DerivedProperty { get; set; } = 73;
public DerivedMock() {
SetupAll(this, this);
}
public static void SetupAll<TDerived>([NotNull] Mock<TDerived> mock, [NotNull] TDerived instance)
where TDerived : class, IDerived {
BaseMock.SetupAll(mock, instance);
mock.SetupGet(o => o.DerivedProperty).Returns(instance.DerivedProperty);
}
}
public class UnitTest1
{
public void Test() {
BaseMock baseMock = new BaseMock();
IBase baseObject = baseMock.Object;
baseMock.BaseProperty = 37;
Assert.AreEqual(37, baseObject.BaseProperty);
baseMock.VerifyGet(o => o.BaseProperty, Times.Never);
// ----------------
DerivedMock derivedMock = new DerivedMock();
IDerived derivedObject = derivedMock.Object;
derivedMock.BaseProperty = 42;
derivedMock.DerivedProperty = 73;
Assert.AreEqual(42, derivedObject.BaseProperty);
Assert.AreEqual(73, derivedObject.DerivedProperty);
}
}
reason why i wrote it this way is that i can dynamicall change property value AND verify that it was readed / written.
You don't inherit from the Mock class. Instead you use Mock's Object property to get the mocked object. To reuse setting up IBase mock, you can do something like this:
private static void SetupBase<T>(Mock<T> mock)
where T : class, IBase
{
// setup base methods and properties
mock.SetupGet(x => x.BaseProperty).Returns(1);
}
private static void SetupDerived(Mock<IDerived> mock)
{
SetupBase(mock);
// setup derived methods and properties
}
[Test]
public void Test()
{
var derivedMock = new Mock<IDerived>();
SetupDerived(derivedMock);
var derived = derivedMock.Object;
Assert.AreEqual(1, derived.BaseProperty);
derivedMock.SetupGet(x => x.BaseProperty).Returns(2);
Assert.AreEqual(2, derived.BaseProperty);
}
Related
I have 2 classes:
public class GenericClass<T>
{
public T Item {get;set;}
}
public class StringClass
{
public string Item {get;set;}
}
now i have a GenericClass object and i need to cast it to StringClass object:
var genericObj = new GenericClass<string>();
var stringObj = (StringClass)genericObj; // <---
How to cast / convert from generic class to specific one?
You can't cast one type to the other because the types are unrelated.
You could, however, define a conversion operator:
public class StringClass
{
public string Item { get; set; }
public static explicit operator StringClass(GenericClass<string> generic)
=> new StringClass { Item = generic.Item };
}
Which would allow this syntax:
var genericObj = new GenericClass<string>();
var stringObj = (StringClass)genericObj;
You can't. You would need common inherited type or implement an interface.
With inheritance:
public class GenericClass<T>
{
public T Item {get;set;}
}
public class StringClass : GenericClass<string>
{
}
if your really need it, you can do this way for examle
var stringObj = new StringClass(genericObj);
public class StringClass
{
public string Item { get; set; }
public StringClass(GenericClass<string> genericClass)
{
Item=genericClass.Item;
}
public StringClass(){}
}
or this is more flexible
public interface IGenericClass<T>
{
public T Item { get; set; }
}
public class GenericClass<T>:IGenericClass<T>
{
public T Item { get; set; }
}
public class StringClass
{
public string Item { get; set; }
public StringClass(IGenericClass<string> genericClass)
{
Item=genericClass.Item;
}
public StringClass(){}
}
Using this answer:
var genericObj = new GenericClass<string>();
var stringObj = (StringClass)Convert.ChangeType(genericObj, typeof(StringClass));
Finally i solved using ICloneable,
Here i have a base class named GenericClass, a generic class named GenericClassT, and a class named StringClass.
Inheritance is:
GenericClass <- GenericClassT <- StringClass
Using ICloneable implementation on GenericClass and GenericClassT, adding a CreateObject and CopyTo methods i reach the final goal:
var genericObj = new GenericClass<string>();
var stringObj = (StringClass)genericObj.Clone<StringClass>();
class definitions:
public class GenericClass: ICloneable
{
public string Id {get;set;}
protected virtual ApiRequestResult CreateObject()
{
return new GenericClass();
}
protected virtual void CopyTo(GenericClass obj)
{
obj.Id = Id;
}
public virtual object Clone()
{
var obj = CreateObject();
CopyTo(obj);
return obj;
}
public virtual object Clone<T>() where T: GenericClass
{
var obj = (GenericClass)Activator.CreateInstance(typeof(T));
CopyTo(obj);
return obj;
}
}
public class GenericClass<T>: GenericClass
{
public T Data {get; set;}
protected override GenericClass CreateObject()
{
return new GenericClass<T>();
}
protected override void CopyTo(GenericClass obj)
{
base.CopyTo(obj);
((GenericClass<T>)obj).Data = Data;
}
}
public class StringClass: GenericClass<string>
{
}
I need to create a dll file which contains all the interfaces of the classes but doesn't contain any class.
Because I use these interfaces for a lot of classes it's must be like that:
public interface IClassA
{
string Word { get; }
}
public interface ITest<TClassA> where TClassA : IClassA
{
TClassA A { get; }
}
Example of two classes that implements these interfaces the way I want:
public class ClassA : IClassA
{
public string Word
{
get;
private set;
}
public string Sentence
{
get;
private set;
}
public ClassA(string word, string sentence)
{
this.Word = word;
this.Sentence = sentence;
}
}
public class Test : ITest<ClassA>
{
public ClassA A
{
get;
private set;
}
public Test(ClassA a)
{
this.A = a;
}
}
And I want to do something like that in the main program:
public static void Main(string[] args)
{
ClassA a = new ClassA("hey", "hey world!");
Test t = new Test(a);
Print((ITest<IClassA>)t);
}
public static void Print(ITest<IClassA> t)
{
Console.WriteLine(t.A.Word);
}
But this casting: (ITest<IClassA>)t makes a run time error.
How can I solve it?
thanks!
You should declare Test as
public class Test : ITest<IClassA>
instead of ITest<ClassA>.
Or declare ITest<TClassA> to be covariant on TClassA:
public interface ITest<out TClassA> where TClassA : IClassA
The Test-class implements the concrete ClassA (public class Test : ITest<ClassA>).
So you're trying to cast an ITest<ClassA> to ITest<IClassA> which obviously fails.
If you let the Test-class implement IClassA, the cast works:
public class Test : ITest<IClassA>
{
public IClassA A
{
get; private set;
}
public Test(IClassA a)
{
this.A = a;
}
}
How do I define a factory whose implementations may accept different numbers of parameters?
public abstract class CarFactory
{
public abstract void countStuff(??); //not sure how to define this
}
I would like the factory to be able to create different objects like:
public class BMW : CarFactory
{
public override void countStuff(param1, param2) {}
}
public class Ford : CarFactory
{
public override void countStuff(param1) {}
}
Not sure if "countStuff" should be a factory responsibility, but you could get something similar this way:
public interface ICountParam {}
public class BmwParam : ICountParam
{
public BmwParam(string a)
{
A = a;
}
public string A { get; set; }
}
public class FordParam : ICountParam
{
public FordParam(string a, string b)
{
A = a;
B = b;
}
public string A { get; set; }
public string B { get; set; }
}
public interface ICarFactory<in T> where T : ICountParam
{
void CountStuff(T param);
}
public class BMW : ICarFactory<BmwParam>
{
public void CountStuff(BmwParam param) { }
}
public class Ford : ICarFactory<FordParam>
{
public void CountStuff(FordParam param) { }
}
Usage:
bmw.CountStuff(new BmwParam("A"));
ford.CountStuff(new FordParam("A", "B"));
Using interface inheritance, I would like to have all items from all ancestors in terminal interface/class and I also would like to have a base interface for all derived interfaces/objects (inheritance tree root) for general object processing like Process(IBase b). So, for example, instead of this:
public interface IBase
{
Guid Id {get;}
void SwitchOn();
}
public interface IPart1 : IBase {void DoPart1Specific();}
public interface IPart2 : IBase {void DoPart2Specific();}
public interface ICompound1 : IPart1, IPart2 {}
public class Compound : ICompound1
{
public Guid Id => Guid.Empty; // IBase
public void SwitchOn() {} // IBase
public void DoPart1Specific() {} // IPart1
public void DoPart2Specific() {} // IPart2
}
I would like to have something like this (using pseudo-explicit-interface-implementation notation which of course won't work here):
public class Compound : ICompound1
{
Guid Part1.Id => Guid.Empty; // ICompound1.IPart1
void Part1.SwitchOn() {} // ICompound1.IPart1
void DoPart1Specific() {} // ICompound1.IPart1
Guid Part2.Id => Guid.Empty; // ICompound1.IPart2
void Part2.SwitchOn() {} // ICompound1.IPart2
void DoPart2Specific() {} // ICompound1.IPart2
}
Only not-so-nice and partial solution I'm able to figure out is to replicate all the common stuff in each interface definition, which is too verbose and error prone (in this case the explicit implementation works and let's say it does not matter that the Compound class members can't be public), but there is no base interface available )o:
public interface IPart1Ex
{
Guid Id {get;}
void SwitchOn();
void DoPart1Specific();
}
public interface IPart2Ex
{
Guid Id {get;}
void SwitchOn();
void DoPart2Specific();
}
public interface ICompound1Ex : IPart1Ex, IPart2Ex {}
public class CompoundEx : ICompound1Ex
{
Guid IPart1Ex.Id => Guid.Empty;
void IPart1Ex.SwitchOn() {}
void IPart1Ex.DoPart1Specific() {}
Guid IPart2Ex.Id => Guid.Empty;
void IPart2Ex.SwitchOn() {}
void IPart2Ex.DoPart2Specific() {}
}
It seems like you don't want to inherit from interfaces at all, but rather use composition. Your Compound class needs to hold an instance for Part1 and an instance for Part2. This would give something like:
public interface IPart {
Guid Id { get; }
void SwitchOn();
void Execute();
}
public class Compound
{
private readonly IPart _part1;
private readonly IPart _part2;
public Compound(IPart part1, IPart part2)
{
_part1 = part1;
_part2 = part2;
}
public Guid Part1Id { get { return _part1.Id; } }
public void Part1SwitchOn() { _part1.SwitchOn(); }
public void DoPart1Specific() { _part1.Execute(); }
public Guid Part2Id { get { return _part2.Id; } }
public void Part2SwitchOn() { _part2.SwitchOn(); }
public void DoPart2Specific() { _part2.Execute(); }
}
Or a simpler class would just be:
public class Compound
{
public Compound(IPart part1, IPart part2)
{
Part1 = part1;
Part2 = part2;
}
public IPart Part1 { get; private set; }
public IPart Part2 { get; private set; }
}
and then access them in the calling code using:
var compound = MyMethodWhichCreatesCompound();
var id1 = compound.Part1.Id;
compound.Part2.Execute();
//etc
I think using the new keyword on interface member definitions can help you:
public interface IBase
{
Guid Id {get;}
void SwitchOn();
}
public interface IPart1 : IBase
{
new Guid Id {get;}
new void SwitchOn();
void DoPart1Specific();
}
public interface IPart2 : IBase
{
new Guid Id {get;}
new void SwitchOn();
void DoPart2Specific();
}
I trying to figure out how to write a class where the base class would supply the accessor functions and then the instanced class only needs to supply the values.
Something like this:
public interface IBaseClass
{
int GetHandlerID();
}
public abstract class AbstractClass : IBaseClass
{
private int HandlerID;
public virtual int GetHandlerID()
{
return (this.HandlerID);
}
}
public class MyClass : AbstractClass
{
int HandlerID = 1;
}
class Program
{
static void Main(string[] args)
{
MyClass newClass = new MyClass();
Console.WriteLine("HandlerID: {0}"), newClass.GetHandlerID() );
}
}
It doesn't work this way because the class is going to read the HandlerID in the AbstractClass instead of the MyClass variable. Using Virtual or Abstract isn't valid for variables, so I'm not sure how to do this other than having to implement properties every time a new class is derived.
What I'm trying to do is supply an interface for people to build their own plug-in class and it would use the accessor methods that are supplied with the base class. I don't want to have to implement the same property method every time I create a new instance of the class.
I figured out a way to do what I wanted. This way I can have default getters/setters in the base class and not have to create those in each definition that uses the base. It's not quite what I was looking for, but it'll work.
public abstract class AbstractClass : IBaseClass
{
private int m_HandlerID = 0;
public int HandlerID
{
get { return (this.m_HandlerID); }
set { this.m_HandlerID = value; }
}
private string m_HandlerDescription = "undefined";
public string HandlerDescription
{
get { return this.m_HandlerDescription; }
set { this.m_HandlerDescription = value; }
}
}
public class MyClass: AbstractClass
{
public MyClass()
{
HandlerID = 1;
HandlerDescription = "MyClass";
}
}
class Program
{
static void Main(string[] args)
{
MyClass newClass = new MyClass();
Console.WriteLine("Handler: {0}[{1}]", newClass.HandlerDescription, newClass.HandlerID);
}
}
public abstract class AbstractClass : IBaseClass
{
public AbstractClass(int handlerId)
{
this.HandlerId = handlerId;
}
public int GetHandlerID()
{
return (this.HandlerID);
}
}
public class MyClass : AbstractClass
{
public MyClass():base(1)//specific handler id
}
How about passing the value through the base constructor
The derived class needs able to access the HandlerID to ovewrite it, so you'll need to change it in the abstract class from 'private' to 'protected'.
public interface IBaseClass
{
int GetHandlerID();
}
public abstract class AbstractClass : IBaseClass
{
protected virtual int HandlerID { get; set; }
public virtual int GetHandlerID()
{
return (HandlerID);
}
}
public class MyClass : AbstractClass
{
private int _handlerID = 1;
protected override int HandlerID { get { return _handlerID; } set { _handlerID = value; } }
}
private static void Main(string[] args)
{
var newClass = new MyClass();
Console.WriteLine("HandlerID: {0}", newClass.GetHandlerID());
Console.ReadKey();
}