2

単体テストは機能しますが、web.config ファイルのカスタム構成セクションから値を取得するコードを追加した後、単体テストが機能しなくなります。以下は私のコードです。「//new」でマークされた行は、追加した新しいコードであり、テストを中断します。

public partial class AccountController : Controller
{
    private readonly string _twitterConsumerKey;
    private readonly string _twitterConsumerSecret;
    private readonly string _twitterAccessToken;
    private readonly string _twitterAccessTokenSecret;

    private readonly IUserService _userService;

    public AccountController(IUserService userService)
    {
        if (userService == null)
            throw new ArgumentNullException("userService");


        _userService = userService;

        _twitterConsumerKey = TwitterSettings.Settings.ConsumerKey;  //new code
        _twitterConsumerSecret = TwitterSettings.Settings.ConsumerSecret;  //new code
        _twitterAccessToken = TwitterSettings.Settings.AccessToken;  //new code
        _twitterAccessTokenSecret = TwitterSettings.Settings.AccessTokenSecret;  //new code

    }





public class TwitterSettings : ConfigurationSection
{

    private static TwitterSettings settings = ConfigurationManager.GetSection("Twitter") as TwitterSettings;
    public static TwitterSettings Settings { get { return settings; } }

    [ConfigurationProperty("ConsumerKey", IsRequired = true)]
    public string ConsumerKey
    {
        get { return (string)this["ConsumerKey"]; }
        set { this["ConsumerKey"] = value; }
    }

    [ConfigurationProperty("ConsumerSecret", IsRequired = true)]
    public string ConsumerSecret
    {
        get { return (string)this["ConsumerSecret"]; }
        set { this["ConsumerSecret"] = value; }
    }


    [ConfigurationProperty("AccessToken", IsRequired = true)]
    public string AccessToken
    {
        get { return (string)this["AccessToken"]; }
        set { this["AccessToken"] = value; }
    }

    [ConfigurationProperty("AccessTokenSecret", IsRequired = true)]
    public string AccessTokenSecret
    {
        get { return (string)this["AccessTokenSecret"]; }
        set { this["AccessTokenSecret"] = value; }
    }


}

単体テストでこのコントローラーを呼び出すと。「失敗しました: System.NullReferenceException: オブジェクト参照がオブジェクトのインスタンスに設定されていません」というエラー メッセージが表示されました。ISetting インターフェイスを作成する必要がありますか?

  [Test]
    public void Login_Action_Get_Returns_Login_View()
    {
        // Arrange

        var expectedViewName = "~/Views/Account/Login.cshtml";

       // it breaks here.
        _accountController = new AccountController(_userService.Object, _mappingService.Object, _authenticationService.Object);

        // Act

        var result = _accountController.Login() as ViewResult;

        // Assert

        Assert.AreEqual(expectedViewName, result.ViewName, "View name should be {0}", expectedViewName);
    }
4

2 に答える 2

7

良い習慣は、ユニットを分離してテストすることです。これは、データベース、ファイル システム (構成ファイルを含む) などの環境を抽象化することも意味します。したがって、クラスTwitterSettingsからインターフェイスを抽出します。TwitterSettings

public interface ITwitterSettings
{
    string ConsumerKey { get; set; }
    string ConsumerSecret { get; set; }
    string AccessToken { get; set; }
    string AccessTokenSecret { get; set; }
}

設定によってこのインターフェイスを実装します。

public class TwitterSettings : ConfigurationSection, ITwitterSettings

そして、この依存関係をコントローラーに注入します。

public partial class AccountController : Controller
{
    private readonly IUserService _userService;
    private readonly ITwitterSettings _twitterSettings;

    public AccountController(IUserService userService, 
                             ITwitterSettings twitterSettings)
    {
        if (userService == null)
            throw new ArgumentNullException("userService");    

        _userService = userService;
        _twitterSettings = twitterSettings;
    }   
}

ところで、環境の抽象化により、テストの実行が高速になり、データベース サーバーが応答しない場合や web.config が見つからない場合ではなく、SUT ロジックが壊れている場合にのみテストが失敗します。

于 2012-07-23T08:03:27.490 に答える
2

単体テスト プロジェクトは、独自のアプリケーション コンテキストを実行しているため、MVC プロジェクトの web.config ファイルを使用しません。

テスト プロジェクトのルートに App.Config ファイルを作成し、それにカスタム構成セクションを追加します。今すぐコントローラーのテストを実行して、機能するかどうかを確認してください。これは適切な単体テストではありませんが、カスタム コードが機能することを証明します。

実際の web.config ファイルの有効性をテストする場合は、追加のヘルパー メソッドを記述する必要があります。

このリンクが役立つ場合があります

于 2012-07-23T00:03:13.160 に答える