I have the following code:
[TestMethod()]
public void Test_Changed()
{
var All = repository.GetProducts().Select(c => c.Price).ToList();
var Original = All.ToList();
//The following line updates all prices but should has no effect
//Because I've used ToList already in All query
reducer.ReducePrice(amount);
All.Zip(Original, (f, s) =>
{
if (f == s)
{
Assert.Fail();
}
return f;
});
}
I'd expected that my test would failed but it is passed successfully. I'm really wondering how is this possible? As clearly shown below the All
and Original
variables have same values so why Assert.Fail();
never executed?
If I remove the ToList
from All
query the test should passed as expected because of deferred execution but when I use ToList
the later changes should has no effect. So why my test is passes?
Please also see this:
var res = All.Zip(Original, (f, s) =>
{
if (f == s)
{
Assert.Fail();
}
return f;
});
The result:
But the test result:
Like many LINQ operations, Zip
is lazy - your lambda expression is never being executed, because you're calling Zip
but never using the results.
If you changed your test to do something like:
var list = All.Zip(...).ToList();
Then I suspect you'll see the assertion fail. (Or call Count()
, or anything else that iterates over the whole sequence.)
Or as Jamiec says, add an assertion. It could be as simple as:
Assert.IsFalse(All.Zip(Original, (f, s) => f == s).Any(x => x));
(It really depends on what you're trying to check - different assertions will give you different kinds of information.)
See more on this question at Stackoverflow