Having the following unit test:
public interface ITestMe
{
object[] Values { get; }
}
[Test]
public void Test ()
{
var sut = A.Fake<ITestMe> ();
A.CallTo (() => sut.Values[0]).Returns (4);
Assert.That (sut.Values[0], Is.EqualTo (4));
}
results in the following exception:
System.InvalidCastException : Unable to cast object of type 'System.Linq.Expressions.SimpleBinaryExpression' to type 'System.Linq.Expressions.InvocationExpression'.
at FakeItEasy.Expressions.CallExpressionParser.Parse(LambdaExpression callExpression)
at FakeItEasy.Configuration.FakeConfigurationManager.AssertThatMemberCanBeIntercepted(LambdaExpression callSpecification)
at FakeItEasy.Configuration.FakeConfigurationManager.CallTo(Expression1 callSpecification) at FakeItEasy.A.CallTo(Expression1 callSpecification)
Or maybe I do not know how to specify a fake for an indexer?
The problem arises from the fact that
Values
isn't an indexer. It's a property that returns an array.An unconfigured
Values
will return a zero-length array (because arrays aren't fakeable). That's what's happening here, and()=>sut.Values[0]
would fail if it were ever executed (which FakeItEasy doesn't do).So the real takeaway here is that since
Values
is an array, which is not fakeable (see What can be faked?), there's no way to have FakeItEasy choose a return value for a particular offset. The best that can be done is to haveValues
return an array of your choosing, as @CharlesMager suggests. For example: