7

私はテストに慣れていないので、助けてください。

私は次のクラスを持っています

public delegate void OnInvalidEntryMethod(ITnEntry entry, string message);

public class EntryValidator
{
    public event OnInvalidEntryMethod OnInvalidEntry;

    public bool IsValidEntry(ITnEntry entry, string ticker)
    {
        if (!IsFieldValid(entry, ticker.Trim().Length.ToString(), "0"))
            return false;

        return true;
    }

    private bool IsFieldValid(ITnEntry entry, string actual, string invalidValue)
    {
        if (actual == invalidValue)
        {
            RaiseInvalidEntryEvent(entry);
            return false;
        }

        return true;
    }

    private void RaiseInvalidEntryEvent(ITnEntry entry)
    {
        if (OnInvalidEntry != null)
            OnInvalidEntry(entry, "Invalid entry in list: " + entry.List.Name + ".");
    }
}

これまでテストケースを書いてきましたが、以下に示すようにイベントとデリゲートに苦労しています

[TestFixture]
public class EntryValidatorTests
{
    private EntryValidator _entryValidator;

    private FakeTnEntry _selectedEntry;
    private string _ticker;

    [SetUp]
    public void Setup()
    {
        _entryValidator = new EntryValidator();
        _ticker = "BOL";
    }

    private FakeTnEntry MakeEntry(string ticker)
    {
        return new FakeTnEntry { Ticker = ticker};
    }

    [Test]
    public void IsValidEntry_WithValidValues()
    {
        _selectedEntry = MakeEntry(_ticker);

        Assert.IsTrue(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
    }

    [Test]
    public void IsValidEntry_WithInValidTicker()
    {
        _selectedEntry = MakeEntry("");
        Assert.IsFalse(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
    }
}}

誰か助けてください。ありがとう..

4

3 に答える 3

12

おそらく、匿名メソッドを使用してイベントをサブスクライブするのが最も簡単です。

[Test]
public void IsValidEntry_WithValidValues()
{
    _selectedEntry = MakeEntry(_ticker);
    _entryValidator.OnInvalidEntry += delegate { 
        Assert.Fail("Shouldn't be called");
    };

    Assert.IsTrue(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
}    

[Test]
public void IsValidEntry_WithInValidTicker()
{
    bool eventRaised = false;
    _selectedEntry = MakeEntry("");
    _entryValidator.OnInvalidEntry += delegate { eventRaised = true; };

    Assert.IsFalse(_entryValidator.IsValidEntry(_selectedEntry, _selectedEntry.Ticker));
    Assert.IsTrue(eventRaised);
}

2 番目のテストでは、イベント引数も期待どおりであることを検証することができます。

また、「無効」は 1 つの単語であることに注意してください。したがって、テストはIsValidEntry_WithInvalidTicker. セットアップも気にしません。各テストで新しいローカル変数を宣言するだけです。

于 2013-05-08T20:05:16.683 に答える
2

クラスを再構築して RaiseInvalidEntryEvent を仮想化し、IsValidEntry_WithInValidTicker でモックできるようにし、チケットが無効なときに呼び出されたことを確認します。

次に、RaiseInvalidEntryEvent が anon デリゲートを個別に呼び出すことを確認する別のテストを行います。

単体テストはできるだけアトミックにする必要があり、これらの動作の両方を異なるテストで検証する必要があります。

public delegate void OnInvalidEntryMethod(ITnEntry entry, string message);

public class EntryValidator
{
    public event OnInvalidEntryMethod OnInvalidEntry;

    public bool IsValidEntry(ITnEntry entry, string ticker)
    {
        if (!IsFieldValid(entry, ticker.Trim().Length.ToString(), "0"))
            return false;

        return true;
    }

    private bool IsFieldValid(ITnEntry entry, string actual, string invalidValue)
    {
        if (actual == invalidValue)
        {
            RaiseInvalidEntryEvent(entry);
            return false;
        }

        return true;
    }

    public virtual void RaiseInvalidEntryEvent(ITnEntry entry)
    {
        if (OnInvalidEntry != null)
            OnInvalidEntry(entry, "Invalid entry in list: " + entry.List.Name + ".");
    }
}

// Had to reverse engineer the following since they were not available in the question
public interface ITnEntry
{
    Ticket List { get; set; }
    string Ticker { get; set; }
}

public class TnEntry : ITnEntry
{
    public Ticket List { get; set; }
    public string Ticker { get; set; }
}

public class Ticket
{
    public string Name { get; set; }
}

注: 一部の OOP エバンガリストは、非公開ではなく公開と宣言されている場合に適合します。基本的に、単体テストと TDD には、純粋な OOP とは相容れない要件がいくつかあります。簡単にするために RaiseInvalidEntryEvent を public にしましたが、通常はこれを内部にしてから、InternalsVisibleTo を介してアセンブリを単体テストに公開します。私は過去4年間TDDを行ってきましたが、プライベートを使用することはめったにありません。

そして、単体テストはすぐに行われます(これはVS2012のMSTESTフレームワークを使用していることに注意してください)

[TestClass]
public class UnitTest1
{
    #region TestHelpers

    private ITnEntry MakeEntry(string ticker)
    {
        return new TnEntry {Ticker = ticker, List = new Ticket()};
    }

    #endregion

    [TestMethod]
    public void IsValidEntry_WithValidValues_ReturnsTrue()
    {
        // ARRANGE
        var target = new EntryValidator();
        var selectedEntry = MakeEntry("BOL");

        // ACT
        bool actual = target.IsValidEntry(selectedEntry, selectedEntry.Ticker);

        // ASSERT
        Assert.IsTrue(actual);
    }

    [TestMethod]
    public void IsValidEntry_WithInValidTicker_ReturnsFalse()
    {
        // ARRANGE
        var target = new EntryValidator();
        var selectedEntry = MakeEntry("");

        // ACT
        bool actual = target.IsValidEntry(selectedEntry, selectedEntry.Ticker);

        // ASSERT
        Assert.IsFalse(actual);
    }

    [TestMethod]        
    public void IsValidEntry_WithInvalidTicker_RaisesEvent()
    {
        // ARRANGE
        // generate a dynamic mock which will stub all virtual methods
        var target = Rhino.Mocks.MockRepository.GenerateMock<EntryValidator>();
        var selectedEntry = MakeEntry("");

        // ACT
        bool actual = target.IsValidEntry(selectedEntry, selectedEntry.Ticker);

        // ASSERT
        // assert that RaiseInvalidEntryEvent was called
        target.AssertWasCalled(x => x.RaiseInvalidEntryEvent(Arg<ITnEntry>.Is.Anything));
    }

    [TestMethod]
    public void RaiseInvalidEntryEvent_WithValidHandler_CallsDelegate()
    {
        // ARRANGE
        var target = new EntryValidator();
        var selectedEntry = MakeEntry("");
        bool delegateCalled = false;

        // attach a handler to set delegateCalled to true
        target.OnInvalidEntry += delegate 
        {
            delegateCalled = true;
        };

        // ACT
        target.IsValidEntry(selectedEntry, selectedEntry.Ticker);

        // ASSERT
        Assert.IsTrue(delegateCalled);
    }
}
于 2014-03-10T20:38:14.323 に答える
1

テストではOnInvalidEntry、ダミー メソッドを使用してイベントをサブスクライブし、呼び出しIsValidEntryて結果を確認する必要があります。

于 2013-05-08T20:06:47.350 に答える