42

I have a class with Microsoft.AspNet.Identity.UserManager injected, and I want to expect the userManager.CreateAsync(user, password) method to return a Task where the IdentityResult.Succeeded = true. However, the only available constructors for IdentityResult are failure constructors that will cause Succeeded property to be false.

How does one create an IdentityResult that has Succeeded == true? IdentityResult doesn't implement an interface and Succeeded isn't virtual so I don't see any obvious ways of creating a mock object through Rhino Mocks (which i'm using as my mocking framework).

My method does something like the below. Providing this example to show why I might want to mock this.

 public async Task<IdentityResult> RegisterUser(NewUser newUser) { ApplicationUser newApplicationUser = new ApplicationUser() { UserName = newUser.UserName, Email = newUser.Email }; IdentityResult identityResult = await applicationUserManager.CreateAsync(newApplicationUser, newUser.Password); if(identityResult.Succeeded) { someOtherDependency.DoSomethingAmazing(); } return identityResult; } 

I'm trying to write a unit test that ensures that someOtherDependency.DoSomethingAmazing() is called if identityResult.Succeeded is true. Thanks for any help!

3
  • Sounds like a case for a decorator (en.wikipedia.org/wiki/Decorator_pattern). Commented Oct 9, 2014 at 1:56
  • Yeah I was really trying to reserve that as a last resort. There are a number of methods that return IdentityResult so it would be a pain to wrap all of these.... but I may just have to. Commented Oct 9, 2014 at 2:38
  • As @jaytre mentioned, use var result = IdentityResult.Success will give you an IdentityResult object with Succeeded = true Commented Oct 9, 2014 at 19:43

5 Answers 5

63

Would the static IdentityResult.Success property work? http://msdn.microsoft.com/en-us/library/microsoft.aspnet.identity.identityresult.success(v=vs.108).aspx

Edit: To add some more detail, it seems what you want to do is get your mocked CreateAsync to return an IdentityResult where Suceeded is true. For that I would just return IdentityResult.Success from your mock. There's shouldn't be a need to mock the IdentityResult itself.

Example: How to setup a service that returns Successful identity result.

 applicationUserManagerMock.Setup(s => s.CreateAsync(It.IsAny<ApplicationUser>(), It.IsAny<string>()) ).ReturnsAsync(IdentityResult.Success); 
Sign up to request clarification or add additional context in comments.

8 Comments

What exactly are you suggesting here? I need to force the Success value to be true for my test.
Maybe I'm mistaken with what you want to do, but I would mock out CreateAsync to return IdentityResult.Success. I don't think there's a need to mock out IdentityResult. Just CreateAsync to provide the functionality that you're expecting.
Ah, I misunderstood what this was. The static property actually returns an IdentityResult that is successful. Weird. Anyway, that is indeed exactly what I need. Thanks!
Might be worth stating more clearly - the way to get a "Succeeded" result is to use the IdentityResult.Success static property to generate the instance of the result with Succeeded == true. It is the only way I can see to get a +ve response.
What about returning an IdentityResult that failed?
|
25

To make the Succeeded property equal to True use either of these examples:

return IdentityResult.Success; IdentityResult result = IdentityResult.Success; 

1 Comment

This is the anwer to the question.
4

Further more, to make the Success property returns true

return Identity.Success; 

Then in your implementing code, call the implementing method like this

var result = await RegisterUser(newUser).Result if(result.Succeeded) { //do something } 

Comments

4

Approach is different for Microsoft.AspNet.Identity and Microsoft.AspNetCore.Identity. Bellow I provided solutions for both:

  1. If you are using Microsoft.AspNet.Identity namespace please check following approach:

    In my example I mocked IdentityResult.Success in following way:

    First, IdentityResult has protected constructor:

    protected IdentityResult(bool success); 

    Protected constructor can be accessed from inherited class if you implement like this:

     public class IdentityResultMock : IdentityResult { public IdentityResultMock(bool succeeded) : base(succeeded) { } } 

    Second, in my unit test I configured ResetPasswordAsync() to return identityResult like in below:

    var identityResult = new IdentityResultMock(true); _mockUserManager.Setup(e => e.ResetPasswordAsync(user.Id, model.Code, model.Password)).ReturnsAsync(identityResult); 

    Third, in my controller's action ResetPasswordAsync() will returns result with Successed == true:

    var result = await userManager.ResetPasswordAsync(user.Id, model.Code, model.Password); 

    Basically I implemented new class which inherited IdentityResult and used that in my test cases.

  2. If you are using using Microsoft.AspNetCore.Identity namespace then try following approach:

    IdentityResult in this case does't have protected constructor but it has protected property Succeeded which can be accessed within class who inherited IdentityResult.

    We can achieve like in following example:

    public class IdentityResultMock : IdentityResult { public IdentityResultMock(bool succeeded = false) { this.Succeeded = succeeded; } } var result = new IdentityResultMock(true); Console.WriteLine(result.Succeeded); result.Succeeded = true; // This is not allowed! Please use constructor. 

5 Comments

I tried this but in the public IdentityResultMock(bool succeeded) : base(succeeded) { } I am getting error "IdentityResult doesn't take a constructor with one argument".. Am I doing it correctly?
@Alexander I am not sure what did you try but IdentityResult has protected constructor which accept bool. Please see source code: github.com/aspnet/AspNetIdentity/blob/master/src/… Did you use from namespace: Microsoft.AspNet.Identity?
I am using Microsoft.AspNetCore.Identity namespace. And I find no constructor accepting bool succeeded. For aspnetcore, is this done differently?
@Alexander It looks like that IdentityResult from Microsoft.AspNetCore.Identity namespace has only default constructor. It means that my solution will not work for that case :(
@Alexander I updated answer which has solution for AspNetCore as well.
1
var responseTask = System.Threading.Tasks.Task.FromResult(IdentityResult.Success); _mocAuthService.Stub(s => s.RegisterUser(null)).IgnoreArguments().Return(responseTask); 

If you need a successful IdentityResult then all you need to do is call the Success property. This will give you a successful IdentityResult.

https://msdn.microsoft.com/en-us/library/microsoft.aspnet.identity.identityresult(v=vs.108).aspx

2 Comments

Could you provide some context for the answer? Code is good, but an explanation of the code is even better.
Updated the answer with a comment, hopefully will make it clearer

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.