首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >静态方法的模拟部分

静态方法的模拟部分
EN

Software Engineering用户
提问于 2021-04-21 19:21:03
回答 2查看 276关注 0票数 1

我正在为现有的静态方法设计一个测试:

代码语言:javascript
运行
复制
public static boolean hasPermissions(String username, int pageid) {
    PermissionsService s = new PermissionsService();
    int[] pages = s.getPages(username);
    for (int i = 0; i < pages.length; i++) {
        if (pages[i] == pageid)
           return true;
    }
    return false;
}

我希望操作从服务返回的响应,并建议添加另一个参数hasPermissions( .. , PermissionsService ps)。但是,由于应用程序中有数百个对PermissionEngine.hasPermissions的调用,其他团队(也在使用代码)反对这一更改。

我是否正确地认为,测试就是这样的设计,而我们的静态方法是技术债,因为它的设计没有考虑到TDD?

EN

回答 2

Software Engineering用户

回答已采纳

发布于 2021-04-21 19:52:17

我是否正确地认为,测试就是这样的设计,而我们的静态方法是技术债,因为它的设计没有考虑到TDD?

可以说。

就个人而言,我不认为您应该更改代码以使其更易于测试。这是一个相当普遍的观点,因为软件的目标是解决一些问题。测试并没有直接影响到这一点,使功能变得更复杂显然更不利于解决问题。

也就是说,当很难测试代码时,就很难更改代码。由于更改是不可避免的,因此从长远来看,使您的代码具有灵活性将对您有所帮助。有时候,这种长期的好处并不值得,但它是罕见的。

对于这个特殊的例子,我在注入服务时会有点犹豫。为hasPermissions提供一个简单的抽象是很有用的。抽象的一个更好的地方是在您自己的消费者那里。它可以接受一个接口或委托/函数对象,在生产中调用这个静态函数。然后,您可以在测试中模拟这一点,而不影响所有其他使用者。

从长远来看,重构这种不灵活的实现是可能的。(理想情况下,删除效率极低的线性搜索)

票数 4
EN

Software Engineering用户

发布于 2021-04-22 18:37:37

我是否正确地认为,测试就是这样的设计,而我们的静态方法是技术债,因为它的设计没有考虑到TDD?

技术债务(无论如何,在原始形式中)并不意味着坏代码,或者我们不喜欢的代码。它具体指的是真实域和代码中的设计之间不正确的对齐。

如果我们不能使我们的计划与我们当时所理解的正确的方式来思考我们的金融目标,那么我们就会因为这个分歧而不断地步履蹒跚,这会拖慢我们的脚步。

这只是(随便选):

  • 坏码
  • 代码不是用你现在需要的功能来设计的

其他团队(也在使用代码)反对这一更改。

他们这样做是对的。做一个向后不相容的改变是个糟糕的想法。

相反,你应该做的是以一种向后兼容的方式进行改变,然后(如果必要的话)摒弃旧的做事方式,协商一个时间表,让每个人都能接受新的方法。

严格的方法是创建一个具有您想要的设计的新名称的函数,然后修改旧函数来调用新函数。

至少有两种方法你可以做到这一点。一个是,如您所建议的,创建一个以服务为参数的函数。

代码语言:javascript
运行
复制
public static boolean hasPermissions(String username, int pageid) {
    PermissionsService s = new PermissionsService();
    return hasPermissionsV2(username, pageid, s);
}

public static boolean hasPermissionsV2(String username, int pageid, PermissionsService s) {
    int[] pages = s.getPages(username);
    for (int i = 0; i < pages.length; i++) {
        if (pages[i] == pageid)
           return true;
    }
    return false;
}

另一种可能更适合您的方法是将操作值的代码从可怕的副作用中分离出来。

代码语言:javascript
运行
复制
public static boolean hasPermissions(String username, int pageid) {
    PermissionsService s = new PermissionsService();
    int[] pages = s.getPages(username);
    return hasPermissionsV3(pages, pageid);
}

public static boolean hasPermissionsV3(int [] pages, pageid) {
    for (int i = 0; i < pages.length; i++) {
        if (pages[i] == pageid)
           return true;
    }
    return false;
}

我建议你回顾一下规范;里奇·希基2016年的演讲中有很多关于名字的有趣之处,以及不改变名字含义的好处。

票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/425647

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档