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
google-chrome-extension
jdo
wso2
proxy
deezer
ngrx
nullpointerexception
session
kalman-filter
bookshelf.js
sqlite-net-extensions
pivotal-cloud-foundry
flyway4
webrequest
spring-kafka
correlation
resize
php-7.1
ab-testing
excel-vba-mac
custom-wordpress-pages
kryo
cultureinfo
autosys
icloud-api
p-value
xpages-ssjs
nhapi
entitlements
fifo
jaxb2
bpel
librato
skia
oracle-fusion-middleware
ioio
pdb
catel
copying
webtest
asset-pipeline
sequential
ios5
swisscomdev
sharefile
opshub
sas-visual-analytics
particles.js
taffy
logparser
paxos
boost-multi-index
return-value
yii2-extension
recursive-datastructures
darcs
knockout-components
nodebb
typed-lambda-calculus
pdfclown
minimization
migradoc
static-ip-address
heidisql
rotativa
savon
bstr
fuzzy-search
contact-list
angstrom-linux
disque
actionbardrawertoggle
skype4py
sdf
packagist
pervasive-sql
separator
sdhc
quicklisp
0xdbe
oberon
key-management
inmobi
directoryservices
kineticjs
offloading
tween
tablelayout
relocation
rdtsc
applescript-objc
id3v2
aapt
yorick
seaside
meteor-velocity
html5-notifications
excel-2003
plasma
pygit2
kyotocabinet
rdoc
frameset
datawindow
ticoredatasync
whoosh
deobfuscation
xmlspy
wise
spec#
dbisam
wsdl.exe
uiq3

Resources

Encrypt Message