fakeiteasy


Using Expression Trees as an argument constraint


Can I use an Expression Tree as an argument constraint in a FakeIteasy CallTo assertion?
Given a method on an interface with the following signature:
interface IRepository<TEntity>
{
TEntity Single(Expression<Func<TEntity, bool>> predicate);
Being called in code like so:
Flight flight = repository.Single(f => f.ID == id);
I have in mind a unit test doing something like this:
Expression<Func<Flight, bool>> myExpression = flight => flight.ID == 1;
A.CallTo(() => repository.Single(
A<Expression<Func<Flight, bool>>>.That.Matches(myExpression)))
.Returns(new Flight());
However this produces a warning: Try specifying type arguments explicitly.
I am currently having to use the Ignored property which is not ideal.
The "Matches"-method takes a lambda but you're trying to pass it the expression. What are you trying to say with the "Matches"-call? Are you matching on equality? In that case you'd just write:
A.CallTo(() => repository.Single(myExpression)).Returns(new Flight());
If you want to constrain the expression on something else you'd have to pass a predicate of the type: Func<Expression<Func<Flight, bool>>, bool> to the "Matches"-method.
Thanks Patrik,
Examining the expression was exactly what I needed to do, i.e. parse the expression (f => f.ID == id) and execute the Right side of the == to get its runtime value.
In code this looks like this:
A.CallTo(() => flightRepository.Single(A<Expression<Func<Flight, bool>>>.That
.Matches(exp => Expression.Lambda<Func<int>>(((BinaryExpression)exp.Body).Right).Compile().Invoke() == 1)))
.Returns(new Flight());
However I can't help thinking that there must be a more elegant way to achieve the same end. I'll leave that for another day though.
Thanks again,
Michael McDowell
I had the same problem while attempting to assert an expression as an argument but I was using Moq. The solution should work for you though as well...
I give most of the credit to this answer to a similar question:
Moq Expect On IRepository Passing Expression
It basically says you can do a ToString() on the expressions and compare them. It is kind of hacky but it only has one downside; the variables names in the lambda expression must match.
Here is an example...
[Test]
public void TestWhichComparesExpressions()
{
// setup
_mockRepository.Setup(x => x.GetByFilter(MatchQuery())).Returns(new List<Record>());
// execute
var records = _service.GetRecordsByFilter();
// assert
Assert.IsNotNull(records);
Assert.AreEqual(0, records.Count());
}
private static Expression<Func<DomainRecord, bool>> MatchQuery()
{
return MatchExpression(ServiceClass.QueryForTheRecords); // constant
}
// http://stackoverflow.com/questions/288413/moq-expect-on-irepository-passing-expression/1120836#1120836
private static Expression<Func<DomainRecord, bool>> MatchExpression(Expression<Func<DomainRecord, bool>> expression)
{
return It.Is<Expression<Func<DomainRecord, bool>>>(e => e.ToString() == expression.ToString());
}
I decided to put the expression into a constant on the class which used it which guaranteed it would be the same in the test if someone changed the lambda expressions's variable names.

Related Links

Converting an MOQ property setup to FakeItEasy
Howto loop OrderedAssertions in FakeItEasy 2
FakeItEasy setting property with no get accessor?
FakeItEasy mocked method won't return object, instead nullReferenceException
How to specify the class to use when faking a property?
How can I fake a Class used insite SUT using FakeItEasy
FakeItEasy expectation fail against HashSet comparisons
FakeItEasy AssignsOutAndRefParameters - lazily?
How do I find the underlying Type of a Fake object returned from FakeItEasy?
FakeItEasy ReturnsLazily with out parameter
how to verify that a method was called with an argument of a specific type
How to fake delegates with FakeItEasy
FakeItEasy & “params” arguments
Using Expression Trees as an argument constraint
How to update a property on a parameter using FakeItEasy

Categories

HOME
java
testng
netbeans
openstack
server
stock
amortized-analysis
sharepoint-designer
rdf
yum
portia
android-youtube-api
gorm
facebook-php-sdk
midi
spring-xd
u-sql
windows-azure-storage
windows-phone-7
serverless-framework
uitypeeditor
openrefine
reactcsstransitiongroup
undefined
evopdf
reverse-proxy
orleans
facebook-instant-articles
kvc
lcd
microsoft-sync-framework
pepper
traffic
bootstrap-material-design
elasticsearch-ruby
replaceall
large-file-upload
media-queries
react-chartjs
windows-dev-center
jmonkeyengine
adobe-premiere
web-mining
neuroscience
c11
impersonation
tasker
fedex
no-www
user-accounts
theming
python-c-api
dotnetzip
idisposable
diagnostics
google-perftools
windows-mobile-6.5
qtwebview
pearson
arrow-keys
color-profile
minimization
smart-table
cubes
android-textview
underscore.js-templating
django-debug-toolbar
bstr
testng-dataprovider
qtableview
content-length
tableau-online
arcanist
operator-precedence
clicktag
markers
blending
odata4j
sabredav
clipper
tinn-r
simba
labwindows
hosts-file
adk
krl
celltable
site.master
createwindow
dmx512
infrastructure
filtered-index
castle-monorail
sef
msdev
signal-handling

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App