How to mock the following class:
UserRepository : GenericRepository<User>, IUserRepository
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
I am using Moq, and I am confused how to handle multiple interfaces correctly.
Take a look at https://github.com/Moq/moq4/wiki/Quickstart
Advanced Features
// implementing multiple interfaces in mock
var foo = new Mock<IFoo>();
var disposableFoo = foo.As<IDisposable>();
// now IFoo mock also implements IDisposable :)
disposableFoo.Setup(df => df.Dispose());
There is a mechanism built into Moq for dealing with multiple interfaces.
Say we have an interface IFoo and an implementation of the same Foo. We also have ClientOne that uses IFoo.
We then have an interface IFooBar : IFoo, an implementation FooBar : Foo, IFooBar and a ClientTwo that uses IFooBar.
When creating an end-to-end test for the system we have an IFooBar, ClientOne and ClientTwo. The As<>() function allows us to use the Mock<IFooBar> as a Mock<IFoo>.
public interface IFoo {
int Id { get; }
}
public class Foo : IFoo {
public int Id {
get { return 1; }
}
}
public interface IFooBar : IFoo {
string Name { get; }
}
public class FooBar : Foo, IFooBar {
public string Name {
get { return "AName"; }
}
}
public class ClientOne {
private readonly IFoo foo;
public ClientOne(IFoo foo) {
this.foo = foo;
}
public string Details {
get { return string.Format("Foo : {0}", foo.Id); }
}
}
public class ClientTwo {
private readonly IFooBar fooBar;
public ClientTwo(IFooBar fooBar) {
this.fooBar = fooBar;
}
public string Details {
get { return string.Format("Foo : {0}, Bar : {1}", fooBar.Id, fooBar.Name); }
}
}
[TestMethod]
public void TestUsingBothClients() {
var fooBarMock = new Mock<IFooBar>();
var fooMock = fooBarMock.As<IFoo>();
fooBarMock.SetupGet(mk => mk.Id).Returns(1);
fooBarMock.SetupGet(mk => mk.Name).Returns("AName");
var clientOne = new ClientOne(fooMock.Object);
var clientTwo = new ClientTwo(fooBarMock.Object);
Assert.AreEqual("Foo : 1", clientOne.Details);
Assert.AreEqual("Foo : 1, Bar : AName", clientTwo.Details);
}
If I understand the question correctly, you want have a single mock instance of UserRepository, and for the purposes of a test, setup calls to methods from both the IGenericRepository<TEntity> interface and the IUserRepository interface.
You can implement multiple interfaces with a single mock instance like this:
var genericRepositoryMock = new Mock<IGenericRepository<User>>();
genericRepositoryMock.Setup(m => m.CallGenericRepositoryMethod()).Returns(false);
var userRepositoryMock = genericRepositoryMock.As<IUserRepository>();
userRepositoryMock.Setup(m => m.CallUserRepositoryMethod()).Returns(true);
However, as D Stanley pointed out, the need to do this is probably an indication that there is a flaw in your design.
You can spare a bit with declaring a common interface just for testing, like:
interface IA { void Work(); }
interface IB { void Rest(); }
class AB: IA, IB
{
public void Work() { ... }
public void Rest() { ... }
}
interface IABTest : IA, IB
{}
class SomeTest
{
public void DoTest()
{
var ab = new Mock<IABTest>();
ab.Setup(m => m.Work());
ab.Setup(m => m.Rest());
}
}
Related
I want to decorate all created instances, that are derived from a specific interface.
public interface IInterface
{
void Execute(); //// only this shall be intercepted
}
public interface IDerivedInterface : IInterface
{
bool CanExecute { get; } //// this shall not be intercepted
}
public class DirectImplementation : IInterface
{
public void Execute()
{
}
}
public class DerivedImplementation : IDerivedInterface
{
public void Execute()
{
}
public bool CanExecute { get; }
}
public class Decorator : IInterface
{
public Decorator(IInterface inner)
{
Inner = inner;
}
public IInterface Inner { get; }
public void Execute()
{
Console.WriteLine("Something is executed");
Inner.Execute();
}
}
My expectation is implemented in this unit test
[Test]
public void Should_know_how_structure_map_works()
{
var container = new Container(
c =>
{
c.For<IInterface>().Use<DirectImplementation>();
c.For<IDerivedInterface>().Use<DerivedImplementation>();
c.For<IInterface>().DecorateAllWith<Decorator>();
});
var interfaceImpl = container.GetInstance<IInterface>();
var derivedInterfaceImpl = container.GetInstance<IDerivedInterface>();
Assert.That(interfaceImpl, Is.TypeOf<Decorator>());
Assert.That(((Decorator)interfaceImpl).Inner, Is.TypeOf<DirectImplementation>());
Assert.That(derivedInterfaceImpl, Is.TypeOf<Decorator>());
Assert.That(((Decorator)derivedInterfaceImpl).Inner, Is.TypeOf<DerivedImplementation>());
}
But this can obviously not be full filled, since Decorator does not implement IDerivedInterface. So my question is:
Is there any way, to configure StructureMap in such a way, that i can intercept all calls to IInterface.Execute?
Suppose I have an interface registered by 3pty library to the default container
// 3pty lib
public interface IFoo {
SayHello();
SayBye();
}
internal sealed class FooInternal : IFoo { ... }
public static WithFoo(this IServiceCollection serviceCollection) {
serviceCollection.AddScoped<IFoo, FooInternal>();
}
And I do want to overwrite the SayBye() method. I've created a class
class FooProxy : IFoo {
private readonly IFoo baseFoo;
public FooProxy(IFoo baseFoo) {
this.baseFoo = baseFoo;
}
public void SayHello() { baseFoo.SayHello(); }
public void SayBye() { ... }
}
Now the problem I'm facing is how to hook it up to dependency injection.
I've tried:
// leads to infinite recursion death
services.AddScoped<IFoo>((sp) => new FooProxy(sp.GetRequiredService<IFoo>()));
And also:
public class FooProxy : IFoo {
private readonly Func<IFoo> baseFoo;
SayHello() { baseFoo().SayHello(); }
}
// leads to object disposed error
services.AddScoped<IFoo>((sp) => new FooProxy(() => sp.GetRequiredService<IFoo>()));
This is something you can achieve using Decorator Pattern.
For this there is one library.
https://github.com/khellang/Scrutor
service.AddScoped<IFoo,FooConcrete>(); // This I believe register by Third Party
service.Decorate<IFoo,FooProxy>(); // This is you will add.
Another way which is bit not good.
public interface IFooProxy: IFoo
{
}
public class FooProxy : IFooProxy
{
public FooProxy(IFoo foo)
{
}
}
// Configure Sevices
services.AddScoped<IFooProxy,FooProxy>();
How can you cast an interface with a generic type to a common interface?
Lets say we have the following interfaces/objects:
public interface IAction : IAction<object> { }
public interface IAction<T>
{
T PerformAction();
}
public class SomeAction : IAction<string>
{
public string PerformAction()
{
return "some action result value";
}
}
public class OtherAction : IAction<int>
{
public int PerformAction()
{
return 100;
}
}
Then if we try to code it in a console application:
List<IAction> actions = new List<IAction>();
actions.Add(new SomeAction());
actions.Add(new OtherAction());
actions.ForEach(e => Console.WriteLine(e.PerformAction()));
How can we work around the error "cannot convert from 'SomeAction' to 'IAction'"?
Your inheritance hierarchy does not make sense, you should have IAction<T> extend IAction and not the other way around.
You also need to add any common methods you want to call to IAction and, if the methods have the same name and parameters, implement them using an explicit interface implementation. It is on the common interface implementation you will be calling the method.
public interface IAction
{
object PerformAction();
}
public interface IAction<T> : IAction
{
new T PerformAction();
}
public class SomeAction : IAction<string>
{
object IAction.PerformAction()
{
return PerformAction();
}
public string PerformAction()
{
return "some action result value";
}
}
public class OtherAction : IAction<int>
{
object IAction.PerformAction()
{
return PerformAction();
}
public int PerformAction()
{
return 100;
}
}
Calling code
List<IAction> actions = new List<IAction>();
actions.Add(new SomeAction());
actions.Add(new OtherAction());
actions.ForEach(e => Console.WriteLine(e.PerformAction()));
I am struggling to cast in a tree hierarchy structure below is an example of the class hierarchy structure I would really appreciate if someone can point me in the right direction.
I am unable to cast
var myobj2 = (IR<JB>)JR;
Classes:
public class BASEA{ }
public class B: BASEA{ }
public class C: B{ }
public interface IR<T> { }
public abstract class JR<T> : IR<T> where T : B
{ public abstract void SetRule(); }
public class Action: JB<C>
{
public override void SetRule()
{
//Logic
}
}
public static class RuleLib
{
public static void ApplyTest<T>(T obj, IR<T> JB) where T:B
{
var myobj2 = (IR<JB>)JR; //=> does not cast!
}
}
public class Test
{
[Test]
public void demo()
{
var obj = new B();
var action = new Action();
RuleLib.ApplyRule(obj,action);
}
}
For this to work, your IRule interface needs to be covariant. The example given here shows the following covariance:
IEnumerable<Derived> d = new List<Derived>();
IEnumerable<Base> b = d;
This is basically exactly what you're doing. So in your code all you need to do is write
public interface IRule<out T> { ... }
instead of
public interface IRule<T> { ... }
This makes it so that you can cast from an IRule<U> to IRule<V> where U is a subclass of V (e.g. casting from IRule<ShiftAction> to IRule<Job>).
Why doesn't the line marked with //Dont work in the bottom of the code compile?
I want to reuse the WriteMessage method with different Classes, I try to use generics, but I'm not sure how to use it.
class ClassOne
{
public string MethodOne()
{
return ("ClassOne");
}
public string MethodTwo()
{
return ("ClassOne -MethodTwo ");
}
}
class ClassTwo
{
public string MethodOne()
{
return ("ClassTwo");
}
public string MethodTwo()
{
return ("ClassOne -MethodTwo ");
}
}
class Program
{
private static void Main()
{
var objectOne = new ClassOne();
WriteMessage(objectOne);
var objectTwo = new ClassTwo();
WriteMessage(objectTwo);
Console.ReadKey();
}
public static void WriteMessage<T>(T objectA)
{
var text = objectA.MethodTwo(); //Dont Work
Console.WriteLine("Text:{0}", text);
}
}
Try implementing a interface :
Example :
public interface IHasTwoMethods
{
string MethodOne()
string MethodTwo()
}
Implement this inteface on your classes :
class ClassOne : IHasTwoMethods
class ClassTwo : IHasTwoMethods
Then in your generic method do like this :
public static void WriteMessage<T>(T objectA) where T : IHasTwoMethods
{
var text = objectA.MethodTwo(); //Will work
Console.WriteLine("Text:{0}", text);
}
You can read more about interfaces here : http://msdn.microsoft.com/en-us/library/87d83y5b.aspx
This doesn't compile because as far as the compiler is concerned objectA is just an Object.
To get this to work, you need to use a generic type constraint:
public interface MyInterface
{
string MethodTwo();
}
public class A : MyInterface
{
...
}
public class B : MyInterface
{
...
}
public static void WriteMessage<T>(T objectA) where T: MyInterface
{
var text = objectA.MethodTwo(); //Will Work!
Console.WriteLine("Text:{0}", text);
}
MSDN : Constraints on Type Parameters
Since you're passing in a generically-typed object with T, the compiler doesn't know what class you're using--for all it knows, it could be an int or an Application or anything.
What you probably want is to have ClassOne and ClassTwo inherit from another class that has an abstract MethodTwo class that both implement. Something like...
abstract class SuperClass
{
public abstract string MethodOne();
}
class ClassOne : SuperClass
{
public override string MethodOne()
{
return ("ClassOne");
}
}
then in Main:
public static void WriteMessage<T>(T objectA) where T : SuperClass
{
var text = objectA.MethodOne();
Console.WriteLine("Text:{0}", text);
}
Read up on C# inheritance here: http://msdn.microsoft.com/en-us/library/ms173149.aspx