Remember that lambdas are nice shortcuts for anonymous methods -- and
anonymous methods are a compiler shortcut for us writing a standalone
method. If we "reverse engineer" your code into what it will look
like to the compiler, you'll see something like this:
public class Handler
{
...
public void HandleSomethingHappened()
{
_list.ForEachEntry(OnAction);
}
private void OnAction(IEntry entry)
{
entry.DoSomething();
}
...
}
And your test code will have something similar:
[TestMethod]
public void AssertingThatDoSomethingWasCalledForEachEntry()
{
IListOfEntries entriesMock =
MockRepository.GenerateMock<IListOfEntries>();
Handler handler = new Handler(entriesMock);
handler.HandleSomethingHappened();
entriesMock.AssertWasCalled(x => x.ForEachEntry(OnAction));
}
private void OnAction(IEntry entry)
{
entry.DoSomething();
}
As you can see, once all these lambdas are compiled into something the
compiler can use, they're actually two totally different methods --
which is why your unit test is failing. You're calling two different
methods (one is in your Handler class and one is in the Unit Test).
I think you need to re-think how to test this situation. In writing a
unit test for Handler.HandleSomethingHappened(), you'll just want to
make sure that it calls IList.ForEachEntry(). A separate unit test on
the implementation of IList.ForEachEntry() should make sure that the
Action<T> passed in is executed for each item.
Hope this helps.
---
Patrick Steele
http://weblogs.asp.net/psteele
On Thu, Jun 10, 2010 at 2:01 PM, Rastislav Svoboda
<[email protected]> wrote:
> Hi all
>
> I have these two interfaces:
>
> public interface IEntry
> {
> void DoSomething();
> void DoSomethingElse();
> }
>
> public interface IListOfEntries
> {
> void Add(IEntry entry);
> void Remove(IEntry entry);
> void ForEachEntry(Action<IEntry> action);
> }
>
> and some class that I want to test:
>
> public class Handler
> {
> private readonly IListOfEntries _list;
>
> public Handler(IListOfEntries list)
> {
> _list = list;
> }
>
> public void HandleSomethingHappened()
> {
> _list.ForEachEntry(entry => entry.DoSomething());
> }
>
> public void HandleSomethingElseHappened()
> {
> _list.ForEachEntry(entry => entry.DoSomethingElse());
> }
> }
>
> Here are the tests:
>
> [TestMethod]
> public void AssertingThatDoSomethingWasCalledForEachEntry()
> {
> IListOfEntries entriesMock =
> MockRepository.GenerateMock<IListOfEntries>();
> Handler handler = new Handler(entriesMock);
>
> handler.HandleSomethingHappened();
>
> entriesMock.AssertWasCalled(x => x.ForEachEntry(entry =>
> entry.DoSomething()));
> }
>
> [TestMethod]
> public void AssertingThatDoSomethingElseWasCalledForEachEntry()
> {
> IListOfEntries entriesMock =
> MockRepository.GenerateMock<IListOfEntries>();
> Handler handler = new Handler(entriesMock);
>
> handler.HandleSomethingElseHappened();
>
> entriesMock.AssertWasCalled(x => x.ForEachEntry(entry =>
> entry.DoSomethingElse()), o => o.IgnoreArguments());
> }
>
>
> Why the first test fails?
>
> Second works - when I ignore the arguments.
>
> But then if method HandleSomethingElseHappened()
> calls by mistake (copy & paste):
>
> _list.ForEachEntry(entry => entry.DoSomething());
>
> instead of DoSomethingElse()
> I will not know that :-(
>
> Any ideas?
> Thanx for answers
> Rastislav
>
> --
> You received this message because you are subscribed to the Google Groups
> "Rhino.Mocks" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/rhinomocks?hl=en.
>
>
--
You received this message because you are subscribed to the Google Groups
"Rhino.Mocks" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rhinomocks?hl=en.