Я всегда проверяю любые исключения, которые я добавляю в свой метод, включая ArgumentNullException
, ArgumentException
и т. Д. Я просто считаю, что лучше всего их протестировать, и их легко написать.Таким образом, если кто-то когда-нибудь удалит этих охранников, тесты будут прерваны, и вы будете знать.
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void ToSetOnNullThrows()
{
List<string> list = null;
var target = list.ToHashSet();
}
Насколько GetHashCode()
и Equals()
я также проверю их если вы переопределите их .Для GetHashCode()
простой тест состоит в том, чтобы создать два эквивалентных объекта (те же значения, которые используются в хэш-коде) и доказать, что хеш-коды, которые генерируют оба объекта, одинаковы.
[TestMethod]
public void GetHashCodeSameKeysAreSameTest()
{
var key = new CompositeKey<string, int>("A", 13);
var otherKey = new CompositeKey<string, int>("A", 13);
Assert.AreEqual(key.GetHashCode(), otherKey.GetHashCode());
}
Вы можете попробовать чтобы проверить, что два неэквивалентных объекта возвращают разные хеш-коды, но вам нужно убедиться, что используемые вами значения не являются просто коллизией.Это во многом зависит от алгоритма, который вы кодируете в GetHashCode()
.
[TestMethod]
public void GetHashCodeDifferentKeysAreMostLikelyDifferentTest()
{
var key = new CompositeKey<string, int>("A", 13);
var otherKey = new CompositeKey<string, int>("A", 14);
Assert.AreNotEqual(key.GetHashCode(), otherKey.GetHashCode());
}
Для теста Equals () два эквивалентных объекта с одинаковыми полями возвращают true
в Equals()
и false
в двух не-эквивалентные объекты.
[TestMethod]
public void EqualsTest()
{
var key = new CompositeKey<string, int>("A", 13);
var otherKey = new CompositeKey<string, int>("A", 13);
Assert.IsTrue(key.Equals(otherKey));
}
[TestMethod]
public void NotEqualsTest()
{
var key = new CompositeKey<string, int>("A", 13);
var otherKey = new CompositeKey<string, int>("A", 15);
Assert.IsFalse(key.Equals(otherKey));
}
Для еще большего удовольствия я люблю проводить юнит-тесты DateTime
зависимых вещей тоже.Это несколько сложнее, но если поведение метода зависит от DateTime
, я все же хочу провести их модульное тестирование.Таким образом, вы можете создать DateTime
делегат генератора, который по умолчанию возвращает DateTime.Now
, но иметь его, чтобы вы могли установить генератор на конкретный DateTime
.Очень помогает в освещении моей работы, так как я работаю в финансовой индустрии, и большая логика зависит от предпродажного, пострыночного времени и т. Д ...
public class SomeClassThatDependsOnCurrentTime
{
internal Func<DateTime> NowGenerator { get; set; }
public SomeClassThatDependsOnCurrentTime()
{
// default in constructor to return DateTime.Now
NowGenerator = () => DateTime.Now;
}
public bool IsAfterMarketClose()
{
// call the generator instead of DateTime.Now directly...
return NowGenerator().TimeOfDay > new TimeSpan(16, 0, 0);
}
}
Тогда вы простонастроить юнит-тест для ввода определенной даты.