我是新手测试请帮忙。
我有以下课程
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));
}
}}
请有人帮忙吗?感谢..
答案 0 :(得分:11)
使用匿名方法订阅事件可能是最简单的:
[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);
}
在第二个测试中,您可能希望验证事件参数是否也符合预期。
另请注意,“无效”是一个单词 - 因此您的测试应为IsValidEntry_WithInvalidTicker
。我也不打扰设置 - 我只是在每个测试中声明新的局部变量。
答案 1 :(得分: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 evangalists适用于公开而非私有的事情,基本上单元测试和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);
}
}
答案 2 :(得分:1)
您的测试应使用虚拟方法订阅事件OnInvalidEntry
,调用IsValidEntry
并检查结果。