What I want to do is to define one or more Setup(s) to one Return call on multiple method calls of the mocked object; hence avoiding multiple single calls to do Setup().Return()s.
The compiler provides an error when attempting the following which demonstrates the goal, so this is not an appropriate way to achieve that goal.
var mPlatform = new Mock<IPlatformCommunicator>();
mPlatform.Setup(mp => mp.PreStart(It.IsAny<Action<IStatus>>()))
.Setup(mp => mp.Start(It.IsAny<Action<IStatus>>()))
...
.Returns(mockStatusIndeterminate.Object as IStatus);
Is there way to define multiple method calls in Setup to economize the total lines of code?
This is not an option too:
.Setup(mp => mp.PreStart(It.IsAny<Action<IStatus>>()) || mp.Start(It.IsAny<Action<IStatus>>()))
As #Nkosi mentions, not really. But there are options that may work depending on your usage.
SetReturnsDefault
void Main()
{
var fooMock = new Mock<IFoo>();
fooMock.SetReturnsDefault<string>("This is a mocked value");
var foo = fooMock.Object;
Console.WriteLine($"foo.Bar(): {foo.Bar()}");
Console.WriteLine($"foo.Baz(): {foo.Baz()}");
}
public interface IFoo
{
string Bar();
string Baz();
}
Any method that returns a string will return whatever you specify.
The default value provider is similar but across the board.
void Main()
{
var fooMock = new Mock<IFoo>();
fooMock.DefaultValueProvider = new MyDefaultValueProvider();
var foo = fooMock.Object;
Console.WriteLine($"foo.Bar(): {foo.Bar()}");
Console.WriteLine($"foo.Baz(): {foo.Baz()}");
}
public interface IFoo
{
string Bar();
string Baz();
}
public class MyDefaultValueProvider : DefaultValueProvider
{
protected override object GetDefaultValue(Type type, Mock mock)
{
return "This is my default value";
}
}
Create your own extension; the following is a working mvp
void Main()
{
var fooMock = new Mock<IFoo>();
fooMock.Setup(new Expression<Func<IFoo, string>>[] { x => x.Bar(), x => x.Baz() }, "This is a mocked value");
var foo = fooMock.Object;
Console.WriteLine($"foo.Bar(): {foo.Bar()}");
Console.WriteLine($"foo.Baz(): {foo.Baz()}");
}
public interface IFoo
{
string Bar();
string Baz();
}
public static class MoqExtensions
{
public static Mock<T> Setup<T, U>(this Mock<T> self, Expression<Func<T, U>>[] setups, U returns)
where T : class
{
foreach (var setup in setups)
{
self.Setup(setup).Returns(returns);
}
return self;
}
}
All of the above produce the following result
You could create your own extension method on Mock<T> that does what you want:
public static class MoqExt {
public static void SetupReturnOnAll<T, TResult>(
this Mock<T> mock,
TResult returnValue,
params Expression<Func<T, TResult>>[] expressions)
where T: class {
foreach (var expr in expressions)
mock.Setup(expr).Returns(returnValue);
}
}
Usage looks like this:
mPlatform
.SetupReturnOnAll(
mockStatusIndeterminate.Object as IStatus,
mp => mp.PreStart(It.IsAny<Action<IStatus>>()),
mp => mp.Start(It.IsAny<Action<IStatus>>()));
With some extra effort to could improve the interface to this:
mPlatform
.SetupAll(
mp => mp.PreStart(It.IsAny<Action<IStatus>>()),
mp => mp.Start(It.IsAny<Action<IStatus>>()))
.Return(mockStatusIndeterminate.Object as IStatus);
For that you'll need an extra class though:
public class MultiSetup<T, TResult>
where T: class {
public Mock<T> Mock { get; }
public Expression<Func<T, TResult>>[] Expressions { get; }
public MultiSetup(Mock<T> mock, Expression<Func<T, TResult>>[] expressions)
=> (Mock, Expressions) = (mock, expressions);
public void Return(TResult returnValue) {
foreach (var expr in Expressions)
Mock.Setup(expr).Returns(returnValue);
}
}
And you'd create it with this extension:
public static class MoqExt {
public static MultiSetup<T, TResult> SetupAll<T, TResult>(
this Mock<T> mock,
params Expression<Func<T, TResult>>[] expressions)
where T : class
=> new MultiSetup<T, TResult>(mock, expressions);
}
Related
Hi I am trying to mock the following thing:
var result = _scope.Execute<FooService, IList<FooEntity>>(x => x.GetFooEntities(fooModel));
This is how I try to mock it:
_mockedScope
.Setup(x => x.Execute<FooService, IList<FooEntity>>(f => f.GetFooEntities(It.IsAny<FooModel>())))
.Returns(new List<FooEntity>)
But when I run the test it throws me an exception
Unsupported expression: s => s.GetFooEntities(IsAny())
Any suggestions how can I mock it?
Here is an example what i want to moq
public class Test
{
private readonly IScope _scope;
public Test(IScope scope)
{
_scope = scope;
}
public void Foo()
{
var foo = new FooEntity();
Result<IList<Foo>> result =
_scope.Execute<FooService, IList<Foo>>(
"f",
s => s.GetFoo(foo));
}
}
public class Foo
{
}
public class FooEntity
{
}
public class FooService
{
public List<Foo> GetFoo(FooEntity f);
}
public interface IScope
{
Result<TResult> Execute<T1, TResult>(string temp, Func<T1, TResult> function);
}
public class Result<T>
{
private Result(T value, Exception exception)
{
Value = value;
Error = exception;
}
public Exception Error { get; }
public T Value { get; }
public bool HasError => Error != null;
public static Result<T> Fail(Exception exception) => new Result<T>(default(T), exception);
public static Result<T> Success(T value) => new Result<T>(value, null);
}
While expressions are used by moq to setup mocks, you are trying to mock an expression. This tends to be very difficult with Moq but there are workarounds via matched arguments.
Assuming Scope.Execute method is defined like
public interface IScope {
Result<TResult> Execute<T, TResult>(string temp, Func<T, TResult> function);
}
Use It.IsAny to allow for flexibility when setting up a mock that relies on an expression argument.
_mockedScope
.Setup(x => x.Execute<FooService, IList<Foo>>(It.IsAny<string>(), It.IsAny<Func<FooService, IList<Foo>>>()))
.Returns(Result<IList<Foo>>.Success(new List<Foo>()));
The It.IsAny<Func<FooService, IList<Foo>>>() will cover s => s.GetFoo(foo) in the invoked code.
Given
public class Test {
private readonly IScope _scope;
public Test(IScope scope) {
_scope = scope;
}
public IList<Foo> Foo() {
var foo = new FooEntity();
Result<IList<Foo>> result = _scope.Execute<FooService, IList<Foo>>("f", s => s.GetFoo(foo));
var value = result.Value;
return value;
}
}
The following complete example was used to demonstrate what was explained above
[TestClass]
public class ExpressionMock {
[TestMethod]
public void TestFoo() {
//Arrange
var _mockedScope = new Mock<IScope>();
_mockedScope
.Setup(x => x.Execute<FooService, IList<Foo>>(It.IsAny<string>(), It.IsAny<Func<FooService, IList<Foo>>>()))
.Returns(Result<IList<Foo>>.Success(new List<Foo>()));
var subject = new Test(_mockedScope.Object);
//Act
var actual = subject.Foo();
//Assert
actual.Should().NotBeNull();
}
}
Reference Moq Quickstart to get a better understanding of how to use the framework
I'm starting with generics types and I'm stuck with my project. Maybe I did not understand generics very well. Explanations have been inserted inline. Basically I need to implement the Do() method but I don't know how to resolve <T2>:
public abstract class MyGenericClass<T> { }
public class MyGenericClass<T, T2> : MyGenericClass<T>
{
public Expression<Func<T, T2>> expression;
public MyGenericClass(Expression<Func<T, T2>> expression)
{
this.expression = expression;
}
}
public class MyClass<T>
{
// I need to mantain a list of my generic class for later use.
// I don't know T2 at this point.
// So I Chose to use Inheritance as a workaround (MyGenericClass<T> and MyGenericClass<T, T2>).
// Maybe it's not a good solution but I counldn't find out other solution.
public List<MyGenericClass<T>> MyGenericList = new List<MyGenericClass<T>>();
// I receive the parametric argument T2 here as part of an Expresion.
// And I keep the expression in my list.
public MyGenericClass<T, T2> ReceivingMethod<T2>(Expression<Func<T, T2>> expression)
{
MyGenericClass<T, T2> genericImp = new MyGenericClass<T, T2>(expression);
MyGenericList.Add(genericImp);
return genericImp;
}
}
public class Client<T>
{
MyClass<T> class1;
// class1 has been created and his field MyGenericList has been populated.
// Then when I call Do()....
public void Do()
{
foreach (var item in class1.MyGenericList)
{
// I need something like this here,
// but it does not compile because I don't know T2 here.
// The caller of Do() method doesn't know T2.
MyGenericClass<T, T2> myGenericItem = (MyGenericClass<T, T2>)item;
var a = myGenericItem.expression;
}
}
}
You have to give Do() the T2 parameter somehow. So my solution is to create a method parameter of the same type. I also nested the types in order to make sure all of them refer to the same T.
I also renamed the parameters to be more descriptive
// T -> TArg
// T2 -> TResult
public abstract class MyBaseClass<TArg>
{
public class MyExpressionClass<TResult> : MyBaseClass<TArg>
{
public Expression<Func<TArg, TResult>> Expression { get; private set; }
public MyExpressionClass(Expression<Func<TArg, TResult>> expression)
{
this.Expression=expression;
}
}
public class MyCollectionClass
{
public List<MyBaseClass<TArg>> MyGenericList = new List<MyBaseClass<TArg>>();
public MyExpressionClass<TResult> ReceivingMethod<TResult>(Expression<Func<TArg, TResult>> expression)
{
var genericImp = new MyExpressionClass<TResult>(expression);
MyGenericList.Add(genericImp);
return genericImp;
}
}
public class Client
{
public MyCollectionClass List = new MyCollectionClass();
public void Do<TResult>()
{
foreach(var item in List.MyGenericList)
{
var expr = item as MyExpressionClass<TResult>;
if(expr!=null)
{
var a = expr.Expression;
Console.WriteLine(a);
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
var client = new MyBaseClass<int>.Client();
// add conversion expressions
client.List.ReceivingMethod((i) => (i).ToString());
client.List.ReceivingMethod((i) => (2*i).ToString());
client.List.ReceivingMethod((i) => (3*i).ToString());
// The programmer has to manually enforce the `string` type
// below based on the results of the expressions above. There
// is no way to enforce consistency because `TResult` can be
// _any_ type.
client.Do<string>();
// Produces the following output
//
// i => i.ToString()
// i => (2*i).ToString()
// i => (3*i).ToString()
}
}
Solution 1 Inspired from #KMoussa comment. I've delegate the responsability to MyGenericClass using an abstract method. This seems a better design. All subclasses will implement this method DoTheWork(). And can be invoked from my Client.Do() method with only T param:
public abstract class MyGenericClass<T>
{
public abstract string DoTheWork();
}
public class MyGenericClass<T, T2> : MyGenericClass<T>
{
public override string DoTheWork()
{
// I can use expression here
}
private Expression<Func<T, T2>> expression { get; set; }
public MyGenericClass(Expression<Func<T, T2>> expression)
{
this.expression = expression;
}
}
public class MyClass<T>
{
public List<MyGenericClass<T>> MyGenericList = new List<MyGenericClass<T>>();
public void ReceivingMethod<T2>(Expression<Func<T, T2>> expression)
{
MyGenericClass<T, T2> genericImp = new MyGenericClass<T, T2>(expression);
}
}
public class Client<T>
{
MyClass<T> class1;
public void Do()
{
// I don't need to cast to MyGenericClass<T, T2>
foreach (MyGenericClass<T> myGenericItem in class1.MyGenericList)
{
string result = myGenericItem.DoTheWork();
}
}
}
Solution 2 Inspired from #ja72 and #juharr comments. Using reflection. First I save the type T2 on MyGenericClass using an abstract property. Then I can invoke a generic method MethodWithArgument using reflection so I can introduce the parameter for the casting:
public abstract class MyGenericClass<T>
{
public abstract Type type { get; set; }
}
public class MyGenericClass<T, T2> : MyGenericClass<T>
{
public Expression<Func<T, T2>> expression { get; set; }
public MyGenericClass(Expression<Func<T, T2>> expression)
{
type = typeof(T2); // I save the type of T2
this.expression = expression;
}
}
public class MyClass<T>
{
public List<MyGenericClass<T>> MyGenericList = new List<MyGenericClass<T>>();
public void ReceivingMethod<T2>(Expression<Func<T, T2>> expression)
{
MyGenericClass<T, T2> genericImp = new MyGenericClass<T, T2>(expression);
}
}
public class Client<T>
{
MyClass<T> class1;
public void Do()
{
foreach (MyGenericClass<T> myGenericItem in class1.MyGenericList)
{
MethodInfo method = GetType().GetMethod("MethodWithArgument");
MethodInfo generic = method.MakeGenericMethod(new Type[] { myGenericItem.type });
string g = (string)generic.Invoke(this, new object[] { myGenericItem });
}
}
// I introduce T2 in this method
public string MethodWithArgument<T2>(MyGenericClass<T> myClass)
{
// Now, the casting is valid
MyGenericClass<T, T2> mySubClass = (MyGenericClass<T, T2>)myClass;
var a = mySubClass.expression;
// I can work with expression here
}
}
I want to create the class Foo as follows.
The Foo constructor input expression has to get some member of Type T to do some work.
class Foo<T>
{
public Foo<TResult>(Expression<Func<T, TResult>> selector)
{
List<string> memberNames = typeof(TR).GetProperties().Select(p => p.Name).ToList();
....//some work on memberNames
}
}
and create Foo<T> instance by this code:
Foo<ClassA> foo = new Foo<ClassA>(u=>new{u.Property1, u.Property2});
However, this did not work and gave the following error:
Constructor can't have Generic type TResult.
How can I fix this?
Edit:
After struggling to understand the expression I found an answer and have written it as an answer.
You can move the logic outside of consrtuctor to separate method. Instead of using constructor to create Foo - you can use static method, like this:
class Foo<T> {
private Foo() {
}
private void Init<TResult>(Expression<Func<T, TResult>> selector) {
List<string> memberNames = typeof(TResult).GetProperties().Select(p => p.Name).ToList();
//some work on memberNames
}
public static Foo<T> Create<TResult>(Expression<Func<T, TResult>> selector) {
var foo = new Foo<T>();
foo.Init(selector);
return foo;
}
}
And use it like this:
Foo<ClassA> foo = Foo<ClassA>.Create(u=>new{u.Property1, u.Property2});
I solve that as follow
class ClassA
{
public int MyProperty { get; set; }
public int MyProperty2 { get; set; }
}
class Foo<T>
{
public Foo(Expression<Func<T, Object>> selector)
{
var props = ((NewExpression)selector.Body).Members.Select(p => p.Name).ToList();
}
}
Foo<ClassA> foo = new Foo<ClassA>(u => new { u.MyProperty, u.MyProperty2 });
I am trying to create an extension method to list the properties in the lambda expression.
Let say there is a Class named Example
public class Example {
Public string Name {get;set;}
Public string Description {get;set;}
}
the extension method can be something like below
public static void GetProperties<T>(this T obj) where T : new()
{
}
Expected usage : this.GetProperties<Example>(m=>m.
so when i type m=>m. should display both the properties (Name,Description).
I think you need to used Func:
public static void GetProperties<T, V>(this T obj, Func<T, V selector) where T : new()
{
}
Usage:
Example ex = new Example();
ex.GetProperties(m => m.Name); // Func<Example, string>
ex.GetProperties(m => m.Description); // Func<Example, string>
I really didn't understand the expected behavior inside the method. But you mentioned m.Name and m.Description. So a property selector is your way.
Func<Example, string> is a function that accepts an Example input parameter and returns a string (which is the property in case of Name and Description).
public static class PropertyUtility
{
public static string GetPropertyName<T>(this T entity, Expression<Func<T, object>> exp)
{
if (exp.Body is MemberExpression) {
return ((MemberExpression)exp.Body).Member.Name;
}
else {
var op = ((UnaryExpression)exp.Body).Operand;
return ((MemberExpression)op).Member.Name;
}
}
}
And use like this:
Example ex = new Example();
var property = ex.GetPropertyName(x => x.Description);
Consider an interface like this:
new Provider().For(myClass).ExcludeProperties("Height", "Width");
public IEditableStateProvider For(object target) {...}
public IEditableStateProvider ExcludePropertyNames(params string[] propertyNames) {...}
I want to replace the params string[] propertyNames arg with params Expression<Func<object>>[] propertyNames so that I would instead have the following.
new Provider().For(myClass).ExcludeProperties(()=>Height, ()=>Width);
I have seen code similar to this so I think it should work, but I am not getting it yet. How can I get this to work?
EDIT - doing this without Generics
Here is some code from an open source project I was looking at where type inference is working without any generics. I was looking to do the same but I don't see where the type inference is coming from (I do see it working though!)
// USAGE (here this is being called from code-behind of a WPF window
private void TrackSelectedTab() {
Services.Tracker.Configure(tabControl)
.AddProperties(() => tabControl.SelectedIndex);
Services.Tracker.ApplyState(tabControl);
}
private void TrackMainWindow() {
Services.Tracker.Configure(this)
.AddProperties(
() => Height,
() => Width,
() => Left,
() => Top,
() => WindowState)
.SetKey("MainWindow")
.SetMode(PersistModes.Automatic);
Services.Tracker.ApplyState(this);
}
// Collab classes
public class SettingsTracker
{
public TrackingConfiguration Configure(object target) {
...
return config;
}
}
public class TrackingConfiguration
{
public TrackingConfiguration AddProperties(params Expression<Func<object>>[] properties) {
...
return this;
}
}
static class Services
{
public static readonly SettingsTracker Tracker = new SettingsTracker(ObjectStore);
}
You should create a generic Provider class in addittion to a non-generic one, so you can take advantage of type inference and type safety:
Interface:
interface IEditableStateProvider<T>
{
IEditableStateProvider<T> For(T target);
IEditableStateProvider<T> ExcludePropertyNames(params Expression<Func<T, object>>[] excludedProperties);
}
Dummy implementation:
class Provider<T> : IEditableStateProvider<T>
{
public IEditableStateProvider<T> For(T target)
{
// dummy
return this;
}
public IEditableStateProvider<T> ExcludePropertyNames(params Expression<Func<T, object>>[] excludedProperties)
{
// dummy
return this;
}
}
class Provider
{
// generic factory method to make use of type inference
public static IEditableStateProvider<T> For<T>(T obj)
{
return new Provider<T>().For(obj);
}
}
Usage:
var myClass = new List<object>(); // or whatever
Provider.For(myClass).ExcludePropertyNames(x => x.Count);
The type T is now infered when you call .For(myClass), and you can now access the properties of type T in a type safe manner via a lambda when calling ExcludePropertyNames.
If you really want a non-generic version:
interface IEditableStateProvider
{
IEditableStateProvider For(object target);
IEditableStateProvider ExcludePropertyNames(params Expression<Func<object>>[] excludedProperties);
}
class Provider : IEditableStateProvider
{
public IEditableStateProvider For(object target)
{
// dummy
return this;
}
public IEditableStateProvider ExcludePropertyNames(params Expression<Func<object>>[] excludedProperties)
{
// dummy
return this;
}
}
var myClass = new List<object>();
new Provider().For(myClass).ExcludePropertyNames(() => myClass.Count);
but please note my comment below.