9

I have a service faked using FakeitEasy and i am trying to call its method. Here is the Code

        var client = container.Resolve<MyService>();
        A.CallTo(() => client.GetUserProfile(userName)).Returns(null);

The method GetUserProfile returns some object in actual implementation. but for some reason i want this method to return null. I am using above code to acomplish this purpose but its returning Fake object instead of null.

Here is the Test Setup i am using

    [Test]
    public void MyTest(string sitecollectionGuid, string customerName)
    {
        var mockHttpContext = SetupHttpContext(sitecollectionGuid, customerName);

        var client = container.Resolve<MyService>();
        A.CallTo(() => client.GetUserProfile(userName)).Returns(null);

        var controllerContext = new ControllerContext(mockHttpContext, new RouteData(), A.Fake<ControllerBase>());
        controller.ControllerContext = controllerContext;

        var result = controller.CheckUsername(userName);
        Assert.IsNotNull(result, "Result is not as expected");
    }

Production Method looks like the following

public UserDAO GetUserProfile(string userName)
    {
        UserDAO objUserProfile = new UserDAO();
        IUsers objUsers = (IUsers)Global.Container["Users"];
        IUser objUser = objUsers.GetByUserName(userName);
        if (objUser == null)
        {

            return null;
        }
        else
        {
            objUserProfile = AutoMapper.Mapper.Map<IUser, UserDAO>(objUser);
            objUserProfile.FirstName = objUser.FirstName;
            objUserProfile.MiddleName = objUser.MiddleName;
            objUserProfile.LastName = objUser.LastName;
            ....................
            ....................
            <setting other properties>
            .................... 
            ....................

            return objUserProfile;
        }
    }

Any help will be appreciated

Thanks

Ranjit
  • 107
  • 1
  • 6
  • Ranjit, can you show us how you create `client` and (probably more importantly) what `userName` is and how you end up invoking `client.GetUserProfile` in your production code? My guess is that when `GetUserProfile` is called, it's with a different value than `userName` has in the test setup. – Blair Conrad Sep 05 '14 at 09:59
  • Hi Blair, UserName is just a string and client.GetUserProfile(userName) returns UserDAO object which only contains data related to the user(userName). – Ranjit Sep 05 '14 at 10:09
  • Still, the value of `userName` when 1) the fake is configured, and 2) `GetUserProfile` is actually called by the production code matter. If we're going to be able to help, we'll need to see more of the test setup and the production code. For example, in addition to the full test, we'll need to see the signature of `GetUserProfile` and the path that's taken between the test and how that method is exercised in the production code. – Blair Conrad Sep 05 '14 at 10:15
  • Blair, i've updted the post with test and production code. Please take a look. – Ranjit Sep 05 '14 at 10:36

3 Answers3

9

Try and type your (null) reference.

UserDAO returnValue = null;    
var client = container.Resolve<MyService>();
        A.CallTo(() => client.GetUserProfile(userName)).Returns(returnValue);
Andreas Lundgren
  • 12,043
  • 3
  • 22
  • 44
1

In order to configure a method, it has to be virtual, abstract, or defined on an interface that you're faking. However,

public UserDAO GetUserProfile(string userName)

is neither virtual nor abstract, so unless you're creating a fake from an interface, this will not work. However, A.CallTo will raise an error when trying to configure either a non-virtual method or a method on a concrete (not faked) object, and you've not mentioned either of these things happening.

From your code, we still can't tell

  1. where client came from (I know, the container, but how did it get there?),
  2. whether controller uses the same client, and
  3. what the connection between controller.CheckUsername and client.GetUserProfile is

My guesses at this point are

  1. whatever controller is using to CheckUsername, it's not the same client that the test has, or
  2. client.GetUserProfile is being called with the wrong userName (although you use the same one in controller.CheckUsername(userName), so that seems less likely)

If you're unable or unwilling to connect the dots, I suggest checking the value of userName at all points, and making sure that when client is called in the production code, it's a faked object (debug in and examine the type—it should be clear whether its your type or the faked one).

Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
  • HI Blair, Thank you for your comments but, My only question was If i want to return NULL from a public method using FakeItEasy. Is It possible ? That's the whole purpose of the question. – Ranjit Sep 09 '14 at 04:56
  • 1
    @Ranjit. It's absolutely possible. This syntax is correct: `A.CallTo(() => client.GetUserProfile(userName)).Returns(null);`, assuming that `client` is a fake. I mention all the other points because you say you tried that and it didn't work, suggesting there's more going on in your code than meets the eye. I was trying to guide you toward an answer as to why that may be so. – Blair Conrad Sep 09 '14 at 10:15
1

or you could just cast the null to the type in context.

var client = container.Resolve<MyService>();
        A.CallTo(() => client.GetUserProfile(userName)).Returns((UserDAO) returnValue);
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Ranjan
  • 63
  • 1
  • 2
  • 7