9

I want to test a method to check that it saves a transaction correctly. Inside it calls Membership.GetUser() to verify the user which causes the test to fail each time. Is there any way to mock this so that Membership.GetUser() always returns a valid name?

I'm using Moq, C# and ASP.Net 4.5 MVC

JohnCambell
  • 633
  • 8
  • 23

2 Answers2

5

In short, you can't. That's why every call to such a "service" should be hidden behind an abstraction.

You can see a sample of that in default MVC template.

Sergei Rogovtcev
  • 5,804
  • 2
  • 22
  • 35
  • 1
    Can you elaborate? The template uses WebSecurity.Login(). What's a good way to abstract that so that the unit tests don't actually hit the database? – Scott Anderson Sep 29 '12 at 15:48
  • 2
    Found this that looks promising: http://blog.spontaneouspublicity.com/unit-testing-the-mvc4-account-controller. Is that the kind of abstraction you are talking about? – Scott Anderson Sep 29 '12 at 15:57
3

Yes, like Serg said, you can mock this by providing an interface for the real service to implement. This interface would have the public methods you are calling, such as:

public interface IMyServiceInterface
{
    IMembershipUser GetUser();
    // other methods you want to use...
}

In your unit tests, you would say:

var mockService = new Mock<IServiceInterface>();
mockService.Setup(mock => mock.GetUser()).
    Returns(new MembershipUserImplementation("MyTestUser", otherCtorParams));

In my example I would create a wrapper for MembershipUser as well as it seems like it also needs to be behind an abstraction.

sfogle
  • 386
  • 3
  • 7