1

Following is the code for which I want to write unit tests:

public virtual ActionResult TryIt()
{
    MemberViewModel viewModel = new MemberViewModel();

    _memberViewModelLookupBuilder.PopulateSelectLists(viewModel);

    return View(viewModel);
}

I want to write unit tests to fake the MemberViewModel object so that I can write tests for rest of the operations in action. Something like -

A.CallTo(() => viewModel = new TryItViewModel()).Returns(viewModel);

But this doesn't work and gives an error saying

"An expression tree may not contain an assignment operator"

Can anyone please advice how I can achieve this?

I am using xUnit and FakeItEasy in my test project.

Any help on this much appreciated.

Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
Nirman
  • 6,715
  • 19
  • 72
  • 139

1 Answers1

2

FakeItEasy cannot impose arbitrary behaviour on concrete methods, for example class constructors. You have to start with a fake and configure it.

This can be accomplished by injecting a fake MemberViewModel into the TryIt method. The typical route would be to extract an interface from MemberViewModel (or even better, rely on an existing one), fake it, and pass it to TryIt. So TryIt becomes:

public virtual ActionResult TryIt(IMemberViewModel viewModel)
{
     _memberViewModelLookupBuilder.PopulateSelectLists(viewModel);
    return View(viewModel);
}

And in your production code you would pass in a new MemberViewModel. The tests would then fake out the object:

var fakeMemberViewModel = A.Fake<IMemberViewModel>();
A.CallTo(() => fakeMemberViewModel.SomeMethod()).Returns(17);

TryIt(fakeMemberViewModel);

…

For another example, see the FakeItEasy Quickstart.

Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
  • I think Mock framework is providing the ability to fake the class constructors using "Setup" methods, if I am not wrong. Not sure, if the provided solution going to work in larger scale projects. I mean, there shouldn't be an easy task to create Interfaces for each and every ViewModel. I believe FakeItEasy should have some mechanism to allow this. – Nirman Oct 15 '15 at 13:38
  • 1
    @Nirman, I don't understand all of your comments: "I think Mock framework is providing the ability to fake the class constructors using "Setup" methods," Aside from that, I see the suggested approach work every day in quite a large enterprise software system. That being said, I understand it's not all that convenient. Due to the platform FakeItEasy is built on, faking constructors is not feasible. However, other mocking frameworks, such as [Isolator](http://www.typemock.com/isolator-product-page) and [JustMock](http://www.telerik.com/products/mocking.aspx) do support mocking constructors. – Blair Conrad Oct 15 '15 at 14:58