non-public dynamic API
This commit is contained in:
Родитель
dad296f3f9
Коммит
327d7113c3
|
@ -123,6 +123,7 @@
|
|||
<Reference Include="Microsoft.CompilerServices.AsyncTargetingPack.Silverlight5">
|
||||
<HintPath>.\Microsoft.CompilerServices.AsyncTargetingPack.Silverlight5.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.CSharp, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||
<Reference Include="Microsoft.Silverlight.Testing">
|
||||
<HintPath>..\Telerik.JustMock.Silverlight\References\Microsoft.Silverlight.Testing.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -169,6 +170,9 @@
|
|||
<Compile Include="..\Telerik.JustMock.Tests\DelegateFixture.cs">
|
||||
<Link>DelegateFixture.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Telerik.JustMock.Tests\DynamicFixture.cs">
|
||||
<Link>DynamicFixture.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Telerik.JustMock.Tests\EventsFixture.cs">
|
||||
<Link>EventsFixture.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -1529,6 +1529,9 @@
|
|||
<Compile Include="..\Telerik.JustMock\Expectations\Abstraction\IDoInstead.cs">
|
||||
<Link>Expectations\Abstraction\IDoInstead.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Telerik.JustMock\Expectations\Abstraction\IExpressionContainer.cs">
|
||||
<Link>Expectations\Abstraction\IExpressionContainer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Telerik.JustMock\Expectations\Abstraction\IFunc.cs">
|
||||
<Link>Expectations\Abstraction\IFunc.cs</Link>
|
||||
</Compile>
|
||||
|
@ -1580,6 +1583,12 @@
|
|||
<Compile Include="..\Telerik.JustMock\Expectations\CommonExpectation.partial.cs">
|
||||
<Link>Expectations\CommonExpectation.partial.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Telerik.JustMock\Expectations\DynaMock\ExpressionContainer.cs">
|
||||
<Link>Expectations\DynaMock\ExpressionContainer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Telerik.JustMock\Expectations\DynaMock\ExpressionRecorder.cs">
|
||||
<Link>Expectations\DynaMock\ExpressionRecorder.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\Telerik.JustMock\Expectations\EventWaitDuration.cs">
|
||||
<Link>Expectations\EventWaitDuration.cs</Link>
|
||||
</Compile>
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
using System;
|
||||
|
||||
#if NUNIT
|
||||
using NUnit.Framework;
|
||||
using TestCategory = NUnit.Framework.CategoryAttribute;
|
||||
using TestClass = NUnit.Framework.TestFixtureAttribute;
|
||||
using TestMethod = NUnit.Framework.TestAttribute;
|
||||
using TestInitialize = NUnit.Framework.SetUpAttribute;
|
||||
using TestCleanup = NUnit.Framework.TearDownAttribute;
|
||||
using AssertionException = NUnit.Framework.AssertionException;
|
||||
#elif VSTEST_PORTABLE
|
||||
using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
|
||||
using AssertionException = Microsoft.VisualStudio.TestPlatform.UnitTestFramework.AssertFailedException;
|
||||
#else
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using AssertionException = Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException;
|
||||
#endif
|
||||
|
||||
namespace Telerik.JustMock.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class DynamicFixture
|
||||
{
|
||||
public class TestBed
|
||||
{
|
||||
protected virtual int Value
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public int ValueWrapper
|
||||
{
|
||||
get { return this.Value; }
|
||||
set { this.Value = value; }
|
||||
}
|
||||
|
||||
protected virtual int Get(int x, string y)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public int GetWrapper(int x, string y)
|
||||
{
|
||||
return Get(x, y);
|
||||
}
|
||||
|
||||
protected virtual int this[string x]
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public int GetIndexer(string x)
|
||||
{
|
||||
return this[x];
|
||||
}
|
||||
|
||||
public void SetIndexer(string x, int value)
|
||||
{
|
||||
this[x] = value;
|
||||
}
|
||||
|
||||
protected virtual INode Root
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
public INode RootWrapper
|
||||
{
|
||||
get { return this.Root; }
|
||||
set { this.Root = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public interface INode
|
||||
{
|
||||
string Name { get; }
|
||||
INode Left { get; }
|
||||
INode Right { get; }
|
||||
}
|
||||
|
||||
[TestMethod, TestCategory("Lite"), TestCategory("NonPublic"), TestCategory("DynaMock")]
|
||||
public void ShouldArrangeNonPublicGetterViaDynaMock()
|
||||
{
|
||||
var mock = Mock.Create<TestBed>();
|
||||
dynamic wrapper = Mock.NonPublic.Wrap(mock);
|
||||
Mock.NonPublic.Arrange<int>(wrapper.Value).Returns(123);
|
||||
Assert.Equal(123, mock.ValueWrapper);
|
||||
}
|
||||
|
||||
[TestMethod, TestCategory("Lite"), TestCategory("NonPublic"), TestCategory("DynaMock")]
|
||||
public void ShouldArrangeNonPublicSetterViaDynaMock()
|
||||
{
|
||||
var mock = Mock.Create<TestBed>();
|
||||
dynamic wrapper = Mock.NonPublic.Wrap(mock);
|
||||
Mock.NonPublic.Arrange(wrapper.Value = 123).MustBeCalled();
|
||||
|
||||
mock.ValueWrapper = 100;
|
||||
Assert.Throws<AssertionException>(() => Mock.Assert(mock));
|
||||
|
||||
mock.ValueWrapper = 123;
|
||||
Mock.Assert(mock);
|
||||
}
|
||||
|
||||
[TestMethod, TestCategory("Lite"), TestCategory("NonPublic"), TestCategory("DynaMock")]
|
||||
public void ShouldArrangeNonPublicSetterWithMatchersViaDynaMock()
|
||||
{
|
||||
var mock = Mock.Create<TestBed>();
|
||||
dynamic wrapper = Mock.NonPublic.Wrap(mock);
|
||||
Mock.NonPublic.Arrange(wrapper.Value = ArgExpr.IsAny<int>()).MustBeCalled();
|
||||
|
||||
Assert.Throws<AssertionException>(() => Mock.Assert(mock));
|
||||
mock.ValueWrapper = 77;
|
||||
Mock.Assert(mock);
|
||||
}
|
||||
|
||||
[TestMethod, TestCategory("Lite"), TestCategory("NonPublic"), TestCategory("DynaMock")]
|
||||
public void ShouldArrangeNonPublicMethodViaDynaMock()
|
||||
{
|
||||
var mock = Mock.Create<TestBed>();
|
||||
dynamic wrapper = Mock.NonPublic.Wrap(mock);
|
||||
Mock.NonPublic.Arrange<int>(wrapper.Get(10, "ss")).Returns(123);
|
||||
|
||||
Assert.Equal(0, mock.GetWrapper(20, "dd"));
|
||||
Assert.Equal(123, mock.GetWrapper(10, "ss"));
|
||||
}
|
||||
|
||||
[TestMethod, TestCategory("Lite"), TestCategory("NonPublic"), TestCategory("DynaMock")]
|
||||
public void ShouldArrangeNonPublicMethodWithMatchersViaDynaMock()
|
||||
{
|
||||
var mock = Mock.Create<TestBed>();
|
||||
dynamic wrapper = Mock.NonPublic.Wrap(mock);
|
||||
Mock.NonPublic.Arrange<int>(wrapper.Get(ArgExpr.Matches<int>(x => x > 40), ArgExpr.IsAny<string>())).Returns(123);
|
||||
|
||||
Assert.Equal(0, mock.GetWrapper(20, "ss"));
|
||||
Assert.Equal(123, mock.GetWrapper(50, "dd"));
|
||||
}
|
||||
|
||||
[TestMethod, TestCategory("Lite"), TestCategory("NonPublic"), TestCategory("DynaMock")]
|
||||
public void ShouldArrangeNonPublicIndexerGetterViaDynaMock()
|
||||
{
|
||||
var mock = Mock.Create<TestBed>();
|
||||
dynamic wrapper = Mock.NonPublic.Wrap(mock);
|
||||
|
||||
Mock.NonPublic.Arrange<int>(wrapper["sss"]).Returns(123);
|
||||
|
||||
Assert.Equal(0, mock.GetIndexer("ssd"));
|
||||
Assert.Equal(123, mock.GetIndexer("sss"));
|
||||
}
|
||||
|
||||
[TestMethod, TestCategory("Lite"), TestCategory("NonPublic"), TestCategory("DynaMock")]
|
||||
public void ShouldArrangeNonPublicIndexerSetterViaDynaMock()
|
||||
{
|
||||
var mock = Mock.Create<TestBed>();
|
||||
dynamic wrapper = Mock.NonPublic.Wrap(mock);
|
||||
|
||||
Mock.NonPublic.Arrange<int>(wrapper["sss"] = 1000).MustBeCalled();
|
||||
|
||||
Assert.Throws<AssertionException>(() => Mock.Assert(mock));
|
||||
mock.SetIndexer("sss", 123);
|
||||
Assert.Throws<AssertionException>(() => Mock.Assert(mock));
|
||||
mock.SetIndexer("aaa", 1000);
|
||||
Assert.Throws<AssertionException>(() => Mock.Assert(mock));
|
||||
mock.SetIndexer("sss", 1000);
|
||||
Mock.Assert(mock);
|
||||
}
|
||||
|
||||
[TestMethod, TestCategory("Lite"), TestCategory("NonPublic"), TestCategory("DynaMock")]
|
||||
public void ShouldArrangeNonPublicMemberRecursivelyViaDynaMock()
|
||||
{
|
||||
var mock = Mock.Create<TestBed>();
|
||||
dynamic wrapper = Mock.NonPublic.Wrap(mock);
|
||||
|
||||
Mock.NonPublic.Arrange<string>(wrapper.Root.Left.Left.Right.Name).Returns("abc");
|
||||
|
||||
Assert.Equal("", mock.RootWrapper.Left.Name);
|
||||
Assert.Equal("abc", mock.RootWrapper.Left.Left.Right.Name);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -65,6 +65,7 @@
|
|||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
</Reference>
|
||||
|
@ -104,6 +105,7 @@
|
|||
<DependentUpon>WhenFixture.tt</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="DelegateFixture.cs" />
|
||||
<Compile Include="DynamicFixture.cs" />
|
||||
<Compile Include="EventClassFactory.cs" />
|
||||
<Compile Include="EventsFixture.cs" />
|
||||
<Compile Include="FluentFixture.cs" />
|
||||
|
|
|
@ -63,6 +63,7 @@ namespace Telerik.JustMock.Core.Expressions
|
|||
case ExpressionType.RightShift:
|
||||
case ExpressionType.LeftShift:
|
||||
case ExpressionType.ExclusiveOr:
|
||||
case ExpressionType.Assign:
|
||||
return this.VisitBinary((BinaryExpression)exp);
|
||||
case ExpressionType.TypeIs:
|
||||
return this.VisitTypeIs((TypeBinaryExpression)exp);
|
||||
|
@ -89,6 +90,8 @@ namespace Telerik.JustMock.Core.Expressions
|
|||
return this.VisitMemberInit((MemberInitExpression)exp);
|
||||
case ExpressionType.ListInit:
|
||||
return this.VisitListInit((ListInitExpression)exp);
|
||||
case ExpressionType.Index:
|
||||
return this.VisitIndex((IndexExpression)exp);
|
||||
default:
|
||||
throw new Exception(string.Format("Unhandled expression type: '{0}'", exp.NodeType));
|
||||
}
|
||||
|
@ -376,5 +379,16 @@ namespace Telerik.JustMock.Core.Expressions
|
|||
}
|
||||
return iv;
|
||||
}
|
||||
|
||||
protected virtual Expression VisitIndex(IndexExpression index)
|
||||
{
|
||||
IEnumerable<Expression> args = this.VisitExpressionList(index.Arguments);
|
||||
Expression expr = this.Visit(index.Object);
|
||||
if (args != index.Arguments || expr != index.Object)
|
||||
{
|
||||
return Expression.MakeIndex(expr, index.Indexer, args);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -457,7 +457,6 @@ namespace Telerik.JustMock.Core
|
|||
return type.IsProxy() ? ((IMockMixin)instance).DeclaringType : type;
|
||||
}
|
||||
|
||||
|
||||
public static bool IsImplementedBy(this MethodInfo interfaceMethod, MethodBase implMethod)
|
||||
{
|
||||
var type = implMethod.DeclaringType;
|
||||
|
|
|
@ -1052,6 +1052,37 @@ namespace Telerik.JustMock.Core
|
|||
target = invocation.Expression;
|
||||
args = invocation.Arguments.ToArray();
|
||||
}
|
||||
else if (expr.NodeType == ExpressionType.Assign)
|
||||
{
|
||||
var binary = (BinaryExpression)expr;
|
||||
if (binary.Left is MemberExpression)
|
||||
{
|
||||
var memberExpr = (MemberExpression)binary.Left;
|
||||
if (!(memberExpr.Member is PropertyInfo))
|
||||
throw new MockException("Fields cannot be mocked, only properties.");
|
||||
|
||||
var property = (PropertyInfo)memberExpr.Member;
|
||||
target = memberExpr.Expression;
|
||||
method = property.GetSetMethod(true);
|
||||
args = new[] { binary.Right };
|
||||
}
|
||||
else if (binary.Left is IndexExpression)
|
||||
{
|
||||
var indexExpr = (IndexExpression)binary.Left;
|
||||
target = indexExpr.Object;
|
||||
method = indexExpr.Indexer.GetSetMethod(true);
|
||||
args = indexExpr.Arguments.Concat(new[] { binary.Right }).ToArray();
|
||||
}
|
||||
else throw new MockException("Left-hand of assignment is not a member or indexer.");
|
||||
}
|
||||
else if (expr is IndexExpression)
|
||||
{
|
||||
var index = (IndexExpression)expr;
|
||||
target = index.Object;
|
||||
var property = index.Indexer;
|
||||
method = property.GetGetMethod(true);
|
||||
args = index.Arguments.ToArray();
|
||||
}
|
||||
else throw new MockException("The expression does not represent a method call, property access, new expression or a delegate invocation.");
|
||||
|
||||
// Create the matcher for the instance part of the call pattern.
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
using System.Linq.Expressions;
|
||||
|
||||
namespace Telerik.JustMock.Expectations.Abstraction
|
||||
{
|
||||
public interface IExpressionContainer
|
||||
{
|
||||
Expression Expression { get; }
|
||||
}
|
||||
}
|
|
@ -351,5 +351,13 @@ namespace Telerik.JustMock.Expectations.Abstraction
|
|||
/// <param name="type">Type whose static members will be given non-public access to.</param>
|
||||
/// <returns>Non-public accessor.</returns>
|
||||
PrivateAccessor MakeStaticPrivateAccessor(Type type);
|
||||
|
||||
dynamic Wrap(object instance);
|
||||
|
||||
dynamic WrapType(Type type);
|
||||
|
||||
ActionExpectation Arrange(IExpressionContainer dynamicExpression);
|
||||
|
||||
FuncExpectation<TReturn> Arrange<TReturn>(IExpressionContainer dynamicExpression);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
using System.Dynamic;
|
||||
using System.Linq.Expressions;
|
||||
using Telerik.JustMock.Expectations.Abstraction;
|
||||
|
||||
namespace Telerik.JustMock.Expectations.DynaMock
|
||||
{
|
||||
public class ExpressionContainer : IDynamicMetaObjectProvider, IExpressionContainer
|
||||
{
|
||||
public Expression Expression { get; set; }
|
||||
|
||||
public bool IsStatic { get; set; }
|
||||
|
||||
public ExpressionContainer(Expression expression)
|
||||
{
|
||||
this.Expression = expression;
|
||||
}
|
||||
|
||||
public DynamicMetaObject GetMetaObject(Expression parameter)
|
||||
{
|
||||
return new ExpressionRecorder(parameter, BindingRestrictions.Empty, this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
using System;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Telerik.JustMock.Core;
|
||||
|
||||
namespace Telerik.JustMock.Expectations.DynaMock
|
||||
{
|
||||
internal sealed class ExpressionRecorder : DynamicMetaObject
|
||||
{
|
||||
public ExpressionRecorder(Expression expression, BindingRestrictions restrictions)
|
||||
: base(expression, restrictions)
|
||||
{ }
|
||||
|
||||
public ExpressionRecorder(Expression expression, BindingRestrictions restrictions, object value)
|
||||
: base(expression, restrictions, value)
|
||||
{ }
|
||||
|
||||
private static DynamicMetaObject CreateRecorder(Expression expression, DynamicMetaObjectBinder binder)
|
||||
{
|
||||
return new ExpressionRecorder(Expression.Constant(new ExpressionContainer(expression), binder.ReturnType),
|
||||
BindingRestrictions.GetExpressionRestriction(Expression.Constant(true)));
|
||||
}
|
||||
|
||||
private static Expression FromArg(DynamicMetaObject arg)
|
||||
{
|
||||
if (UnwrapMatcher(arg) != null)
|
||||
{
|
||||
return arg.Value as Expression;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Expression.Constant(arg.Value, arg.LimitType);
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodInfo UnwrapMatcher(DynamicMetaObject arg)
|
||||
{
|
||||
var expr = arg.Value as MethodCallExpression;
|
||||
if (expr != null && expr.Method.GetCustomAttributes(typeof(ArgMatcherAttribute), false).Length != 0)
|
||||
{
|
||||
return expr.Method;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ThrowMissingMemberException(Type type, string name)
|
||||
{
|
||||
throw new MissingMemberException(String.Format("Member named '{0}' not found on type '{1}'.", name, type));
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
|
||||
{
|
||||
var wrapper = this.Value as ExpressionContainer;
|
||||
var valueExpr = wrapper.Expression;
|
||||
var property = PrivateAccessor.ResolveProperty(valueExpr.Type, binder.Name, new object[0], !wrapper.IsStatic);
|
||||
if (property == null)
|
||||
ThrowMissingMemberException(valueExpr.Type, binder.Name);
|
||||
|
||||
var memberExpr = Expression.Property(!wrapper.IsStatic ? valueExpr : null, property);
|
||||
|
||||
return CreateRecorder(memberExpr, binder);
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindSetMember(SetMemberBinder binder, DynamicMetaObject value)
|
||||
{
|
||||
var wrapper = this.Value as ExpressionContainer;
|
||||
var valueExpr = wrapper.Expression;
|
||||
var property = PrivateAccessor.ResolveProperty(valueExpr.Type, binder.Name, new object[0], !wrapper.IsStatic, value.Value, getter: false);
|
||||
if (property == null)
|
||||
ThrowMissingMemberException(valueExpr.Type, binder.Name);
|
||||
|
||||
var memberExpr = Expression.Assign(Expression.Property(!wrapper.IsStatic ? valueExpr : null, property), FromArg(value));
|
||||
|
||||
return CreateRecorder(memberExpr, binder);
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)
|
||||
{
|
||||
var wrapper = this.Value as ExpressionContainer;
|
||||
var valueExpr = wrapper.Expression;
|
||||
var property = PrivateAccessor.ResolveProperty(valueExpr.Type, "Item",
|
||||
indexes.Select(i => i.Value).ToArray(), !wrapper.IsStatic);
|
||||
if (property == null)
|
||||
ThrowMissingMemberException(valueExpr.Type, "Item");
|
||||
|
||||
var memberExpr = Expression.MakeIndex(!wrapper.IsStatic ? valueExpr : null, property, indexes.Select(FromArg));
|
||||
return CreateRecorder(memberExpr, binder);
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)
|
||||
{
|
||||
var wrapper = this.Value as ExpressionContainer;
|
||||
var valueExpr = wrapper.Expression;
|
||||
var property = PrivateAccessor.ResolveProperty(valueExpr.Type, "Item",
|
||||
indexes.Select(i => i.Value).ToArray(), !wrapper.IsStatic, value.Value, getter: false);
|
||||
if (property == null)
|
||||
ThrowMissingMemberException(valueExpr.Type, "Item");
|
||||
|
||||
var memberExpr = Expression.Assign(
|
||||
Expression.MakeIndex(!wrapper.IsStatic ? valueExpr : null, property, indexes.Select(FromArg)),
|
||||
FromArg(value));
|
||||
return CreateRecorder(memberExpr, binder);
|
||||
}
|
||||
|
||||
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
|
||||
{
|
||||
var wrapper = this.Value as ExpressionContainer;
|
||||
var valueExpr = wrapper.Expression;
|
||||
|
||||
var candidateMethods = valueExpr.Type.GetAllMethods()
|
||||
.Where(m => m.Name == binder.Name && m.IsStatic == wrapper.IsStatic)
|
||||
.Where(m =>
|
||||
{
|
||||
var methodParams = m.GetParameters();
|
||||
for (int i = 0; i < args.Length; ++i)
|
||||
{
|
||||
var matcher = UnwrapMatcher(args[i]);
|
||||
if (matcher != null)
|
||||
{
|
||||
var argType = matcher.ReturnType;
|
||||
if (!methodParams[i].ParameterType.IsAssignableFrom(argType))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
var methodArgs = args.Select(a =>
|
||||
{
|
||||
var matcher = UnwrapMatcher(a);
|
||||
return matcher != null ? matcher.ReturnType.GetDefaultValue() : a.Value;
|
||||
}).ToArray();
|
||||
|
||||
object state;
|
||||
var method = (MethodInfo)Type.DefaultBinder.BindToMethod(BindingFlags.Default, candidateMethods, ref methodArgs, null, null, null, out state);
|
||||
|
||||
var memberExpr = Expression.Call(!wrapper.IsStatic ? valueExpr : null, method, args.Select(FromArg).ToArray());
|
||||
|
||||
return CreateRecorder(memberExpr, binder);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ using Telerik.JustMock.Core;
|
|||
using Telerik.JustMock.Core.Behaviors;
|
||||
using Telerik.JustMock.Core.Context;
|
||||
using Telerik.JustMock.Expectations.Abstraction;
|
||||
using Telerik.JustMock.Expectations.DynaMock;
|
||||
|
||||
namespace Telerik.JustMock.Expectations
|
||||
{
|
||||
|
@ -517,5 +518,33 @@ namespace Telerik.JustMock.Expectations
|
|||
{
|
||||
return PrivateAccessor.ForType(type);
|
||||
}
|
||||
|
||||
public dynamic Wrap(object instance)
|
||||
{
|
||||
return ProfilerInterceptor.GuardInternal(() =>
|
||||
new ExpressionContainer(Expression.Constant(instance, MockingUtil.GetUnproxiedType(instance)))
|
||||
);
|
||||
}
|
||||
|
||||
public dynamic WrapType(Type type)
|
||||
{
|
||||
return ProfilerInterceptor.GuardInternal(() =>
|
||||
new ExpressionContainer(Expression.Constant(type.GetDefaultValue(), type)) { IsStatic = true }
|
||||
);
|
||||
}
|
||||
|
||||
public ActionExpectation Arrange(IExpressionContainer dynamicExpression)
|
||||
{
|
||||
return ProfilerInterceptor.GuardInternal(() =>
|
||||
MockingContext.CurrentRepository.Arrange(Expression.Lambda(dynamicExpression.Expression), () => new ActionExpectation())
|
||||
);
|
||||
}
|
||||
|
||||
public FuncExpectation<TReturn> Arrange<TReturn>(IExpressionContainer dynamicExpression)
|
||||
{
|
||||
return ProfilerInterceptor.GuardInternal(() =>
|
||||
MockingContext.CurrentRepository.Arrange(Expression.Lambda(dynamicExpression.Expression), () => new FuncExpectation<TReturn>())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ namespace Telerik.JustMock
|
|||
{
|
||||
args = args ?? MockingUtil.NoObjects;
|
||||
var candidates = type.GetAllMethods()
|
||||
.Where(m => m.Name == name && CanCall(m))
|
||||
.Where(m => m.Name == name && CanCall(m, this.instance != null))
|
||||
.ToArray();
|
||||
object state;
|
||||
var method = MockingUtil.BindToMethod(MockingUtil.AllMembers,
|
||||
|
@ -144,7 +144,7 @@ namespace Telerik.JustMock
|
|||
{
|
||||
return ProfilerInterceptor.GuardInternal(() =>
|
||||
{
|
||||
var prop = ResolveProperty(name, indexArgs);
|
||||
var prop = ResolveProperty(this.type, name, indexArgs, this.instance != null);
|
||||
return ProfilerInterceptor.GuardExternal(() => SecuredReflectionMethods.GetProperty(prop, this.instance, indexArgs));
|
||||
});
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ namespace Telerik.JustMock
|
|||
{
|
||||
ProfilerInterceptor.GuardInternal(() =>
|
||||
{
|
||||
var prop = ResolveProperty(name, indexArgs, value, getter: false);
|
||||
var prop = ResolveProperty(this.type, name, indexArgs, this.instance != null, value, getter: false);
|
||||
ProfilerInterceptor.GuardExternal(() => SecuredReflectionMethods.SetProperty(prop, this.instance, value, indexArgs));
|
||||
});
|
||||
}
|
||||
|
@ -224,7 +224,7 @@ namespace Telerik.JustMock
|
|||
throw new MissingMemberException(String.Format("Couldn't find {0} '{1}' on type '{2}'.", kind, name, this.type));
|
||||
}
|
||||
|
||||
private PropertyInfo ResolveProperty(string name, object[] indexArgs, object setterValue = null, bool getter = true)
|
||||
internal static PropertyInfo ResolveProperty(Type type, string name, object[] indexArgs, bool hasInstance, object setterValue = null, bool getter = true)
|
||||
{
|
||||
var candidates = type.GetAllProperties().Where(prop => prop.Name == name).ToArray();
|
||||
if (candidates.Length == 1)
|
||||
|
@ -238,7 +238,7 @@ namespace Telerik.JustMock
|
|||
|
||||
var propMethods = candidates
|
||||
.Select(prop => getter ? prop.GetGetMethod(true) : prop.GetSetMethod(true))
|
||||
.Where(m => m != null && CanCall(m))
|
||||
.Where(m => m != null && CanCall(m, hasInstance))
|
||||
.ToArray();
|
||||
|
||||
indexArgs = indexArgs ?? MockingUtil.NoObjects;
|
||||
|
@ -252,9 +252,9 @@ namespace Telerik.JustMock
|
|||
return type.GetAllFields().FirstOrDefault(f => f.Name == name);
|
||||
}
|
||||
|
||||
private bool CanCall(MethodBase method)
|
||||
private static bool CanCall(MethodBase method, bool hasInstance)
|
||||
{
|
||||
return method.IsStatic || this.instance != null;
|
||||
return method.IsStatic || hasInstance;
|
||||
}
|
||||
|
||||
private object CallInvoke(MethodBase method, object[] args)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>..\..\..\Binaries\Debug\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;DOTNET35;NO_ASSEMBLY_SCANNING;NO_EXCEPTION_SERIALIZATION</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;NO_ASSEMBLY_SCANNING;NO_EXCEPTION_SERIALIZATION</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
@ -35,7 +35,7 @@
|
|||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>..\..\..\Binaries\Release\</OutputPath>
|
||||
<DefineConstants>TRACE;DOTNET35;NO_ASSEMBLY_SCANNING;NO_EXCEPTION_SERIALIZATION</DefineConstants>
|
||||
<DefineConstants>TRACE;NO_ASSEMBLY_SCANNING;NO_EXCEPTION_SERIALIZATION</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<DocumentationFile>..\..\..\Binaries\Release\Telerik.JustMock.xml</DocumentationFile>
|
||||
|
@ -48,7 +48,7 @@
|
|||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseFree|AnyCPU'">
|
||||
<OutputPath>..\..\..\Binaries\ReleaseFree\</OutputPath>
|
||||
<DefineConstants>TRACE;DOTNET35;LITE_EDITION;NO_ASSEMBLY_SCANNING;NO_EXCEPTION_SERIALIZATION</DefineConstants>
|
||||
<DefineConstants>TRACE;LITE_EDITION;NO_ASSEMBLY_SCANNING;NO_EXCEPTION_SERIALIZATION</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
|
@ -60,13 +60,14 @@
|
|||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugFree|AnyCPU'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>..\..\..\Binaries\DebugFree\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;DOTNET35;LITE_EDITION;NO_ASSEMBLY_SCANNING;NO_EXCEPTION_SERIALIZATION</DefineConstants>
|
||||
<DefineConstants>TRACE;DEBUG;LITE_EDITION;NO_ASSEMBLY_SCANNING;NO_EXCEPTION_SERIALIZATION</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.XML" />
|
||||
|
@ -535,6 +536,9 @@
|
|||
<Compile Include="Core\TransparentProxy\MockingProxy.cs" />
|
||||
<Compile Include="Core\TransparentProxy\ProxyInvocation.cs" />
|
||||
<Compile Include="DebugView.cs" />
|
||||
<Compile Include="Expectations\Abstraction\IExpressionContainer.cs" />
|
||||
<Compile Include="Expectations\DynaMock\ExpressionContainer.cs" />
|
||||
<Compile Include="Expectations\DynaMock\ExpressionRecorder.cs" />
|
||||
<Compile Include="Helpers\TaskHelper.cs" />
|
||||
<Compile Include="Setup\DisableAutomaticRepositoryResetAttribute.cs">
|
||||
<SubType>Code</SubType>
|
||||
|
|
Загрузка…
Ссылка в новой задаче