我应该为参数异常编写测试吗?

发布于 2024-12-02 19:09:36 字数 201 浏览 1 评论 0原文

应用 TDD 时,您是否创建测试来验证参数的预期异常(ArgumentException、ArgumentNullException、InvalidOperation 等)或仅验证“已知”异常,例如 CustomerDelinquentException ?

equals、gethashcode 重写怎么样?我将如何测试 gethashcode?

谢谢

When applying TDD, do you create tests that verify expected exceptions for arguments (ArgumentException, ArgumentNullException, InvalidOperation, etc.) or just ones that are "known", for example, CustomerDelinquentException ?

What about equals, gethashcode overrides? how would i test gethashcode?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深居我梦 2024-12-09 19:09:36

我总是测试我在方法中抛出的任何异常,包括 ArgumentNullExceptionArgumentException 等。我发现最好测试这些异常,而且它们很容易编写。这样,如果有人移除这些守卫,测试就会失败,你就会知道。

    [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() 测试,两个具有相同字段的等效对象在 Equals() 上返回 true,在两个非等效对象上返回 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);
    }
}

然后您只需设置一个单元测试来注入特定的日期时间。

I always test for any exceptions I throw in my method, including ArgumentNullException, ArgumentException, etc. I just find it's best to test these and they're easy to write. That way if someone ever removes those guards, the tests would break and you'd know.

    [TestMethod]
    [ExpectedException(typeof(ArgumentNullException))]
    public void ToSetOnNullThrows()
    {
        List<string> list = null;
        var target = list.ToHashSet();
    }

As far as GetHashCode() and Equals() i test these as well if you override them. For GetHashCode() an easy test is to create two equivalent objects (same values used in the hash code) and prove that the hash codes both objects generate are the same.

    [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());
    }

You can try to test that two non-equivalent objects return different hash codes, but you'd have to make sure the values you use aren't simply a collision. This largely depends on the algorithm you code in 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());
    }

For Equals() test that two equivalent objects with the same fields return true on Equals() and false on two non-equivalent objects.

    [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));
    }

For even more fun, I like to unit tests DateTime dependent stuff too. This is somewhat harder, but if a method's behavior depends on DateTime i still want to unit test them. So you can create a DateTime generator delegate that defaults to returning DateTime.Now but have it so that you can set the generator to a specific DateTime. Helps a lot with coverage in my line of work since I'm in the financial industry and a lot of logic depends on pre-market, post-market hours, etc...

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);
    }
}

Then you just set up a unit test to inject a specific date time.

墨小墨 2024-12-09 19:09:36

如果您的代码测试参数并引发异常,那么是的,您应该测试这些异常。如果没有或另外,您应该使用无效值测试您的代码,看看会发生什么。

当您期望两个对象相等时,您也应该测试 equals,即测试 gethashcode。

If your code tests arguments and throws exceptions, then yes, you should test for those exceptions. If not or in addition, you should test your code with invalid values to see what happens.

You should test for equals as well, that kind of tests gethashcode too, when you expect two objects to be equal.

好菇凉咱不稀罕他 2024-12-09 19:09:36

是的。不要忘记单元测试也可以作为文档的一种形式。它向使用您的组件的下一个开发人员或客户显示他们正在调用的函数或方法的先决条件。

Yes. Don't forget that unit tests serves as a form of documentation too. It shows to the next developer or clients using your component the preconditions of the function or method they are calling.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文