private static Expression ConvertToSetup(Expression targetObject, Expression left, Expression right) { // TODO: throw if target is a static class? var sourceType = targetObject.Type; var returnType = left.Type; var returnsMethod = typeof(IReturns <,>) .MakeGenericType(sourceType, returnType) .GetMethod("Returns", new[] { returnType }); return(Expression.NotEqual( Expression.Call(FluentMockVisitor.Accept(left), returnsMethod, right), Expression.Constant(null))); }
private static Expression ConvertToSetupProperty(Expression targetObject, Expression left, Expression right) { // TODO: throw if target is a static class? var sourceType = targetObject.Type; var propertyInfo = (PropertyInfo)((MemberExpression)left).Member; var propertyType = propertyInfo.PropertyType; // where foo.Name == "bar" // becomes: // where Mock.Get(foo).SetupProperty(mock => mock.Name, "bar") != null // if the property is readonly, we can only do a Setup(...) which is the same as a method setup. if (!propertyInfo.CanWrite || propertyInfo.GetSetMethod(true).IsPrivate) { return(ConvertToSetup(targetObject, left, right)); } // This will get up to and including the Mock.Get(foo).Setup(mock => mock.Name) call. var propertySetup = FluentMockVisitor.Accept(left); // We need to go back one level, to the target expression of the Setup call, // which would be the Mock.Get(foo), where we will actually invoke SetupProperty instead. if (propertySetup.NodeType != ExpressionType.Call) { throw new NotSupportedException(string.Format(Resources.UnexpectedTranslationOfMemberAccess, propertySetup.ToStringFixed())); } var propertyCall = (MethodCallExpression)propertySetup; var mockExpression = propertyCall.Object; var propertyExpression = propertyCall.Arguments.First().StripQuotes(); // Because Mocks.CreateMocks (the underlying implementation of the IQueryable provider // already sets up all properties as stubs, we can safely just set the value here, // which also allows the use of this querying capability against plain DTO even // if their properties are not virtual. var setPropertyMethod = typeof(Mocks) .GetMethod("SetProperty", BindingFlags.Static | BindingFlags.NonPublic) .MakeGenericMethod(mockExpression.Type.GetGenericArguments().First(), propertyInfo.PropertyType); return(Expression.Equal( Expression.Call(setPropertyMethod, mockExpression, propertyCall.Arguments.First(), right), Expression.Constant(true))); }