首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单元可测试代码:方法可见性与测试复杂性

单元可测试代码:方法可见性与测试复杂性
EN

Software Engineering用户
提问于 2011-04-20 10:17:50
回答 3查看 726关注 0票数 6

我无法决定如何正确地重构代码。假设我有一个复杂的假设逻辑:

代码语言:javascript
复制
public class ImageService
{
     public void UploadImage(VectorData data) {
         var image = ConvertVectorDataToImage();
         var thumbnail = CreateThumbnail(image);
         SaveThumbnail(thumbnail);
         SaveImage(image);
         SendEmail(image);
         ...
     }
}

(如果例子中的某件事是出于单一的责任,那么让我们假装,我可以编一个更好的例子)

如果我使UploadImage可见(公共),那么编写测试就变得复杂了。它们往往很长,很难阅读,如果您想避免代码重复,那么测试中的逻辑就会出现。

如果我使所有这些小片段可见,API就会变得混乱(因为在我的示例中,每个人唯一感兴趣的是UploadImage方法)。更糟糕的是,经过一段时间之后,人们会倾向于使用那些小方法,因为它们是公开的,而不是因为它们应该在类之外使用。

因此,我的问题是,如何在可见性和测试复杂性之间取得平衡?还是我一开始就做错了什么?

EN

回答 3

Software Engineering用户

发布于 2011-04-20 11:10:07

首先,您需要坚持,您应该支持组合而不是继承。这意味着,您不需要尝试通过子类来避免代码重复,而是需要从实现该行为的一组类中组合行为。

您不必担心所有这些类的可见性,就像客户机将看到的接口将是唯一可见的API.一样。

如果其他开发人员重用部分代码,这难道不是一件好事吗?这意味着您已经成功地创建了可重用的构建块。

票数 5
EN

Software Engineering用户

发布于 2011-04-20 13:09:21

您应该开始使用模拟框架和代码来进行接口。

使用原子接口,尽可能使用SRP来描述要执行的任务:

代码语言:javascript
复制
IImageConvertor { ConvertVectorDataToImage }
IThumbnailWorker { CreateThumbnail; SaveThumbnail }

埃塞特拉斯

现在,执行图像上传的类应该有以下每个接口的数据成员:

代码语言:javascript
复制
public class ImageService
{
    IImageConvertor _imageConvertor;
    IThumbnailWorker _thumbnailWorker;
}

然后用你的方法调用

代码语言:javascript
复制
public void UploadImage(VectorData data) {
     var image = _imageConvertor.ConvertVectorDataToImage();
     var thumbnail = _thumbnailWorker.CreateThumbnail(image);
     _thumbnailWorker.SaveThumbnail(thumbnail);
     ...
 }

现在您的模拟框架接管了,所以在测试中您为您的接口创建模拟对象,您的测试只是验证这些接口调用了正确的方法,并且它们被按正确的顺序调用。您实际上不做任何图像操作,也不进行任何文件访问。这样可以保持测试的快速性,并且确实有助于保持代码的解耦和模块化。

您可以分别测试作为每个接口基础的对象。通常,人们不测试诸如文件访问之类的东西,因为它们通常是由语言或第三方API处理的,您所做的只是包装它们,并且在单元测试中很快就会发现任何错误。你是否认为这是一个好主意,这是另一回事。

票数 2
EN

Software Engineering用户

发布于 2011-04-20 10:29:39

代码语言:javascript
复制
src/main/java/net.bobah/example/MyClass.java:
public class MyClass {
  void defaultMethod() { ... } // visible only to classes from the same package
}

src/main/java/net.bobah/example/MyClassTest.java:
public class MyClassTest {
  @Test
  void defaultMethodTest() { ... testInst.defaultMethod(); ... } // works fine
}
票数 0
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

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

复制
相关文章

相似问题

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