2016-07-24 12 views
1

MVC5アプリケーションでは、任意のコントローラーへの呼び出しを記録するLogエンティティがあります。このログでは、HttpContext.Current.User.Identity.GetUserId()を使用して、コントローラにアクセスするユーザーの身元を判別します。HttpContext.Current.User.Identity.GetUserId()を使用したユニットテストmvcモデル

threw exception: System.NullReferenceException: Object reference not set to an instance of an object. at DASU.Core.Models.Log..ctor()

私はコンテキストが設定されていないため、これは知っている:私はユニットテストにコントローラと、ログクラスのインスタンスをクレートをしようとすると

public class Log 
{ 
    public Log() 
    { 
     TS = DateTime.Now; 
     UserId = HttpContext.Current.User.Identity.GetUserId(); 
    } 

    [Required] 
    public Int32 Id { get; set; } 
    public string UserId { get; set; } 

    [Display(Name = "TS", ResourceType = typeof(Resources.Models.Log.Log))] 
    [Required(ErrorMessageResourceType = typeof(Resources.Models.Log.Log), ErrorMessageResourceName = "RequiredTS")] 
    public DateTime TS { get; set; } 

    [Required] 
    public short LogTypeId { get; set; } 

    [Display(Name = "LogText", ResourceType = typeof(Resources.Models.Log.Log))] 
    public string LogText { get; set; } 

    public ApplicationUser User { get; set; } 
} 

は、私はこのエラーを取得します。

私の質問はどのようにコンテキストを設定するのですか、またはコンテキストを偽装する方法です。テストのログを作成できますか?

+0

IoC/DIコンテナを使用していますか?もしそうなら、そのことからユーザーを得ることが最善です。 'HttpContext'からユーザをコンテナに入れるWebフィルタを持つことができます。また、テスト・コンテキストからユーザーをコンテナに入れるテスト・セットアップを行うこともできます。明らかに、これはユニットテストには適用されません。ユニットテストはユーザを気にしないからです。これは統合テストのためのものです。テスト中に他のユニットに避けられないように呼び出すユニットがある場合(あなたのケースでは、LogとHttpContextは別のユニットです)、ユニットテストではありません。ユニットを分けてください。 –

+2

そのような隠れた依存関係を保持する代わりに、コンストラクタのパラメータとしてuserIdを要求する方がはるかに簡単です。 –

答えて

1

HttpContextに接続しないでください。コメントで提案されているようにあなたは私が依存Logクラス

public class Log 
{ 
    public Log(string userId) 
    { 
     TS = DateTime.Now; 
     UserId = userId; 
    } 

    //...other code removed for brevity 
} 

UserIdを注入したり、あなたのアブストラクトを模擬し、代わりにしようとモックのそれを注入することができるようにHttpContextへの呼び出しを抽象化あなたのログを簡素化することができHttpContext

public interface IUserProvider { 
    string GetUserId(); 
} 

あなたの生産の実装はHttpContextへの呼び出しをラップすることができますし、簡単にあなたのユニットテストのためのモック実装を作成することができます。

public class Log 
{ 
    public Log(IUserProvider userProvider) 
    { 
     TS = DateTime.Now; 
     UserId = userProvider.GetUserId(); 
    } 

    //...other code removed for brevity 
} 
関連する問題