Monday, July 9, 2012

Why isn't this test passing? Must be FakeItEasy's fault.

This is a cautionary tale. Before trawling through the different communities trying to work out why something isn't working and step back and look at your code with a bit of common sense.

I had this code in my WorkoutController.



        public ActionResult Edit(Guid id) {

            WorkoutViewModel workout _workoutService.FindById(id);

            if(Request.IsAjaxRequest()) {

                return PartialView("_WorkoutEditView",  workout);

            }

            return View("Edit",  workout);

        }



A part of the Action was being tested by this Unit Test.



        [Test]

        public void EditCallsFindById() {

            Guid newGuid Guid.NewGuid();

            _controller.Edit(newGuid);

            A.CallTo(_workoutService.FindById(Guid.Empty)).WithAnyArguments().MustHaveHappened(Repeated.Exactly.Once);        }



Every time I ran the test it failed and obviously continued to fail. It was driving me nuts. I start looking at the FakeItEasy wiki and started looking at StackOverflow.

I left the problem overnight and came back to it this morning. When I look at the test first thing it hit me. The signature of A.CallTo() that I was looking for was

public static IReturnValueArgumentValidationConfiguration CallTo(Expression<Func> callSpecification)

Hence when I changed my test to:

Code Snippet

        [Test]        public void EditCallsFindById() {
            
            Guid newGuid Guid.NewGuid();

            _controller.Edit(newGuid);

            A.CallTo(()=>_workoutService.FindById(Guid.Empty)).WithAnyArguments().MustHaveHappened(Repeated.Exactly.Once);
        }



That is I need to added the lambda expression.

The moral to this story is always cast a critical eye over your code before really getting into troubleshooting mode.