使用动态语言进行单元测试

7
我在这里看到了一些人询问他们的单元测试的批评。我没有看到它们被关闭,所以我也想这样做。
我编写了这些测试,我认为使用动态(dynamic)可以使其更易读,但我想知道Stack Overflow社区是否有任何补充建议。
我知道使用动态(dynamic)在某种程度上是非常有争议的,并且会在C#开发人员之间引发宗教战。但我真的希望避免这种情况;我只是想撰写一些好的测试来帮助我完成我的工作 :)
    [TestMethod]
    public void TestAllocation() {
        SearchView.StubPropertyNumValueThenSetUpSearchView<WellDetail>("TX", Property.WorkingInterestTaxSubtypeId);
        Presenter.SetUpPhaseAndFmvValues(Phase.PhaseIdForForRenderAppraiser, 1000);

        AddTheseItems(
            new { PropNum = "pn1", CAN = "can1", MostRecentFmv = 10 },
            new { PropNum = "pn1", CAN = "can1", MostRecentFmv = 10 },
            new { PropNum = "pn1", CAN = "can1", MostRecentFmv = 10 },
            new { PropNum = "pn1", CAN = "can1", MostRecentFmv = 10 },

            new { PropNum = "pn1", CAN = "can2", MostRecentFmv = 40 },
            new { PropNum = "pn1", CAN = "can2", MostRecentFmv = 40 },
            new { PropNum = "pn1", CAN = "can2", MostRecentFmv = 40 },

            new { PropNum = "pn2", CAN = "can1", MostRecentFmv = 50 },
            new { PropNum = "pn2", CAN = "can1", MostRecentFmv = 50 });

        Presenter.Process(SearchView, ItemsToProcess);

        AssertTheseItemsExist(
            new { NumberOfTimes = 4, PropNum = "pn1", CAN = "can1", FmvCalculated = 100 },
            new { NumberOfTimes = 3, PropNum = "pn1", CAN = "can2", FmvCalculated = 400 },
            new { NumberOfTimes = 2, PropNum = "pn2", CAN = "can1", FmvCalculated = 500 });
    }

    private void AddTheseItems(params dynamic[] MassUpdateDtos) {
        foreach(dynamic item in MassUpdateDtos)
            ItemsToProcess.Add(new MassFMVUpdateDTO(new WellDetail() { PropertyNum = item.PropNum, CountyAccountNum = item.CAN }, new FMVHistory(), 0, item.MostRecentFmv));
    }

    private void AssertTheseItemsExist(params dynamic[] uniqueTargets) {
        foreach (dynamic target in uniqueTargets)
            Assert.AreEqual(target.NumberOfTimes, ItemsToProcess.Count(f => f.PropertyNum == target.PropNum && f.CountyAccountNum == target.CAN && f.FMV == target.FmvCalculated));
    }

2
@Daniel 我认为这只是使测试更易读;它将焦点放在相关的特定数据部分上。如果我使用适当的静态类型对象(依我之见),AddTheseItems方法会显示测试变得多么臃肿。 - Adam Rackis
@Mike,对于这种用途,我强烈反对使用私有类 - 我认为它们只会使事情变得臃肿,但这纯粹是个人偏好的问题。感谢您的评论。 - Adam Rackis
1
@Adam:你的 AddTheseItems 只需要加上类名即可变长:new Params { PropNum = "pn1", CAN = "can1", MostRecentFmv = 10 }, - Daniel Hilgarth
@Adam:我并不认为像这样使用动态语言存在问题,它基本上只是没有按照原本的意图来使用,所以个人而言,我不会像这样使用它,而是选择私有类... - Daniel Hilgarth
1
@Daniel - 我的理解是,dynamic 的预期用途是作为反射和通信互操作的替代方案,我的理解正确吗? - Adam Rackis
显示剩余5条评论
1个回答

2

使用动态语言可以减少所需代码的行数。但首先要考虑单元测试的目的,你希望它们告诉你代码哪里出了问题。

如果你添加的数据行中有错误,它能告诉你哪一行失败了吗? 如果其中一个断言失败了,它会告诉你是哪一个吗?

只要你能获得所需信息,一切都应该没问题。因此,它应该准确地告诉你出了什么问题以及何时发生。


+1 这是一个很好的观点。从我所了解的情况来看,无论是现在的方式还是如果我添加简单类以避免动态,都不能告诉我具体是哪一行导致了失败。对我来说,我期望测试通过的次数远远大于失败的次数,因此我认为如果我重构代码导致测试失败,我可以直接进入测试。这听起来像是合理的推理吗? - Adam Rackis
当然,编写单元测试的目的就是为了检测错误,一旦发现错误,你希望它们能够准确地指出错误所在。 - MrFox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接