3

commonlibrary(http://commonlibrarynet.codeplex.com/)のCaptchaクラスを使用しています。私のコードはすべて機能しますが、今は単体テストを作成しようとしています。

私の検証ルールは次のとおりです。

 RuleFor(x => x.CaptchaUserInput)
            .NotEmpty()
            .Must((x, captchaUserInput) => Captcha.IsCorrect(captchaUserInput, x.CaptchaGeneratedText))
            .WithMessage("Invalid captcha code");

私のセットアップコードでは、次のことを試みました。

A.CallTo(() => Captcha.IsCorrect()).Returns(true);

しかし、次のエラーメッセージが表示されます。

SetUp : FakeItEasy.Configuration.FakeConfigurationException : 

The current proxy generator can not intercept the specified method for the following reason:
- Static methods can not be intercepted.


at FakeItEasy.Configuration.DefaultInterceptionAsserter.AssertThatMethodCanBeInterceptedOnInstance(Metho    dInfo method, Object callTarget)
at FakeItEasy.Configuration.FakeConfigurationManager.CallTo(Expression`1 callSpecification)
at ProdMaster.Hosts.Web.Tests.Unit.Controllers.AccountControllerTests.SetUp() in     AccountControllerTests.cs: line 44 

したがって、問題は、FakeItEasyを使用して静的メソッドを偽造する方法です。

TIA、

デビッド

4

2 に答える 2

8

FakeItEasyで静的メソッドをインターセプトする方法はありません(現在、他のオープンソースではなく、.Net用の無料のモックフレームワークです)。静力学(および封印されたクラス)をモックできるようにするには、TelerikからTypemockIsolatorまたはJustMockのいずれかを購入する必要があります。

多くの開発者は、統計をコードの臭いと見なしています(ほとんどの場合)。したがって、オープンソースのモックフレームワークがこれをサポートしていないという事実は、より良い設計を促進するため、良いことと見なされます。モックの「ゴールデンルール」は「制御できない場合はモックしない」であるため、発生した問題を解決する一般的な方法は、静的呼び出しのラッパーを作成することです。この--mockable--ラッパーとの相互作用をテストします。System.DateTime.Nowは、テストで頻繁にテストしたい静的な例です。これからテストを分離するには、次のようにします。

public interface ISystemTimeProvider
{
    DateTime Now { get; }
}

public class DateTimeNowSystemTimeProvider
    : ISystemTimeProvider
{
    public DateTime Now
    {
        get
        {
            return DateTime.Now;
        }
    }
}

上記のインターフェースと実装では、SUTはインターフェースに依存します(たとえば、コンストラクターインジェクションを介して)。あなたのテストでは、偽物(A.Fake<ISystemTimeProvider>())を注入します。DateTimeSystemTimeProviderの実装は、単体テストされることはありません。非常に低レベルであり、統合テスト以外のテストは必要ありません。

私はあなたが話しているキャプチャライブラリにあまり精通していないので、その場合に上記のパターンをどのように適用するかは正確にはわかりませんが、何らかの方法で実行できると確信しています。

于 2011-04-23T17:16:10.790 に答える
1

Patrikのソリューションと同様に、この静的メソッドを呼び出すクラスのコンストラクターにデリゲートを渡すことができます。

したがって、デフォルトのコンストラクターでCaptcha.IsCorrectを指すデリゲートを設定します。

このデリゲート変数は、fluentValidationコード内で呼び出されます。単体テスト中に、モックメソッドを指すようにデリゲートを設定する新しいコンストラクターを作成します。(あなたの場合、trueを返すだけです)

public class SomeValidator
{
    Func<string, string, bool> _captchaVerifier;

    public SomeValidator()
    {
        _captchaVerifier = Captcha.IsCorrect;
    }

    public SomeValidator(Func<string, string, bool> method)
    {
        _captchaVerifier = method;
    }

    public void Validate()
    { /* your code */
        RuleFor(x => x.CaptchaUserInput)
        .NotEmpty()
        .Must((x, captchaUserInput) => _captchaVerifier(captchaUserInput, x.CaptchaGeneratedText))
        .WithMessage("Invalid captcha code");
    }
}
于 2014-11-05T07:58:46.480 に答える