web-dev-qa-db-ja.com

ASP.NET Web APIでUser.Identity.Nameを使用するメソッドの単体テストを作成する

ASP.NET Web APIの単体テストを使用してテストケースを作成しています。

これで、次のコード行を使用して、サービスレイヤーで定義したメソッドを呼び出すアクションができました。

string username = User.Identity.Name;
// do something with username
// return something

今、このための単体テストメソッドを作成する方法、null参照例外を取得しています。ユニットテストなどを書くのは初めてです。

そして、私はこれのためだけに単体テストを使いたいです。

これで私を助けてください。ありがとう。

40
Yasser

以下は、これを行う唯一の方法です。

public class FooController : ApiController {

    public string Get() {

        return User.Identity.Name;
    }
}

public class FooTest {

    [Fact]
    public void Foo() {

        var identity = new GenericIdentity("tugberk");
        Thread.CurrentPrincipal = new GenericPrincipal(identity, null);
        var controller = new FooController();

        Assert.Equal(controller.Get(), identity.Name);
    }
}
46
tugberk

NerdDinnerテストチュートリアルで見つけた別の方法を次に示します。私の場合はうまくいきました:

DinnersController CreateDinnersControllerAs(string userName)
{

    var mock = new Mock<ControllerContext>();
    mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);
    mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);

    var controller = CreateDinnersController();
    controller.ControllerContext = mock.Object;

    return controller;
}

[TestMethod]
public void EditAction_Should_Return_EditView_When_ValidOwner()
{

    // Arrange
    var controller = CreateDinnersControllerAs("SomeUser");

    // Act
    var result = controller.Edit(1) as ViewResult;

    // Assert
    Assert.IsInstanceOfType(result.ViewData.Model, typeof(DinnerFormViewModel));
}

必ずセクション全体を読んでください: ser.Identity.Nameプロパティのモック

Moqモックフレームワークを使用します。これは、Test project NuGetの使用: http://nuget.org/packages/moq

16

WebApi 5.0では、これはわずかに異なります。次のことができます。

controller.User = new ClaimsPrincipal(
  new GenericPrincipal(new GenericIdentity("user"), null));
11
jonnii

これは私にとってはうまくいきませんでしたが、Moqを使用してControllerContextにユーザー名を設定する別の質問で解決策を使用しました: https://stackoverflow.com/a/6752924/347455

1
pennstatephil

ユニットテストを実行するとき-私の場合、Windows認証を使用し、Identity.Nameは私のドメイン名です。これもテストのために変更したいです。 IAuthenticationFilterで必要なものを「ハッキング」するようなアプローチ

0
Alexander

これが私の解決策です。

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, "Nikita"),
    new Claim(ClaimTypes.NameIdentifier, "1")
};

var identity = new ClaimsIdentity(claims);
IPrincipal user = new ClaimsPrincipal(identity);

controller.User = user;
0
Nikita

テストするコントローラーがたくさんある場合は、基本クラスを作成し、コンストラクターでGenericIdentityGenericPrincipalを作成してThread.CurrentPrincipalを設定することをお勧めします

GenericPrincipal principal = new GenericPrincipal(new 
    GenericIdentity("UserName"),null); Thread.CurrentPrincipal = principal; 

その後、そのクラスを継承します..そのように、すべての単体テストクラスには、プリンシパルオブジェクトセットがあります

[TestClass]
public class BaseUnitTest
{
    public BaseUnitTest()
    {
      GenericPrincipal principal = new GenericPrincipal(new GenericIdentity("UserName"),null);   
      Thread.CurrentPrincipal = principal;
    }
}


[TestClass]
public class AdminUnitTest : BaseUnitTest
{
   [TestMethod]
   public void Admin_Application_GetAppliction()
   {
   }
}
0
user3507981

ここで、テストメソッドからコントローラーレベルのテスト用のユーザー識別名を設定する別の方法のソリューションを見つけました。

public static void SetUserIdentityName(string userId)
        {
            IPrincipal principal = null;
            principal = new GenericPrincipal(new GenericIdentity(userId), 
            new string[0]);
            Thread.CurrentPrincipal = principal;
            if (HttpContext.Current != null)
            {
                HttpContext.Current.User = principal;
            }
        }
0
Umapathy