- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
假设我们有这个枚举
enum Action: String {
case doThing
case doOtherThing
}
这个枚举是这样使用的:
func run(action: Action, block: () -> Void)
现在,我对 run
方法进行单元测试,因此我需要以这种方式传递 Action
:
func testActionRun() {
let expect = expectation(description: #function)
let sut = ActionRunner()
sut.run(action: .doThing) {
expect.fulfill()
// Assert something
}
waitForExpectations(timeout: 0.1, handler: nil)
}
因为我需要在 ActionRunner
上测试其他情况,所以我在整个测试套件中散布了很多 .doThing
。
问题是:如果我更改生产代码并将 case doThing
更改为 case doThatThing
现在我所有的测试套件都会失败,因为没有 案例 doThing
.
最完美的做法是在测试代码中声明一个虚拟的case
以允许类似
sut.run(action: .dummyAction) {
}
但是 enum
不允许这样做,因为它不允许继承,也不允许扩展来添加 case
。
我想到的第一个选择是将 Action
转换为协议(protocol),但这种更改在生产中是不必要的,它的唯一目的是在测试代码中完成一些事情。
那么,是否还有其他选择可以实现这一目标?
最佳答案
在使用枚举时如何避免耦合是一个棘手的问题。我自己碰到过几次,但没有可靠的答案:/
您提出的一点是使用协议(protocol),这在生产中感觉没有必要。我有点同意这一点,但大多数时候这是必要的邪恶。
在您展示的示例中,尽管我认为设计中的调整可能会解决部分问题。
特别是在查看这段代码时
func run(action: Action, block: () -> Void) {
// ...
}
func testActionRun() {
let expect = expectation(description: #function)
let sut = ActionRunner()
sut.run(action: .doThing) {
expect.fulfill()
// Assert something
}
waitForExpectations(timeout: 0.1, handler: nil)
}
我想到的是您的 Action
指定了某种行为。也就是说,当您测试传递 .doThing
的 run
方法时,您期望的行为与传递 .doOtherThing
时不同。
如果是这样,是否有任何理由需要将操作枚举实例和传递给run
函数?
您可以将定义行为的代码与执行实际操作的代码分开,甚至比您已经完成的还要多。例如:
protocol Actionable {
var action: () -> () { get }
}
enum Action: Actionable {
case doThing
case doOtherThing
var action {
switch self {
case .doThing: return ...
case .doOtherThing: return ...
}
}
class ActionRunner {
func run(actionable: Actionable) {
actionable.action()
}
}
func testActionRun() {
let expect = expectation(description: #function)
let sut = ActionRunner()
sut.run(actionable: FakeActionable()) {
expectation.fulfill()
}
waitForExpectations(timeout: 0.1, handler: nil)
}
class FakeActionable: Actionable {
let action = { }
}
func testDoThing() {
let sut = Action.doThing
sut.action()
// XCTAssert for the expected effect of the action
}
注意:我实际上并没有编译该代码,所以如果其中有一些错误,请多多包涵。它应该给出这个想法。
这样你就有了ActionRunner
,它的唯一目的是正确运行一个给定的Actionable
,还有Action
枚举,它的唯一目的是描述应该执行哪些不同的操作。
此示例代码在其功能上相当受限,仅运行 () -> ()
操作,但您可以在其之上构建以实现更高级的行为。
关于swift - 在测试中使用枚举时避免耦合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45210216/
Law of Demeter表示你应该只与你直接了解的对象交谈。也就是说,不要执行方法链接来与其他对象通信。当您这样做时,您正在与中间对象不恰本地建立不正确的链接coupling您的代码到其他代码。
我已经实现了一个 CodeService,它将从代码表中检索国家/地区列表。 在我的 ShippingService 中,我想检查订单是否运送到某个国家/地区。 在这种情况下,我应该使用 CodeSe
虽然这个论坛上有很多包含耦合和内聚示例的好示例,但我正在努力将其完全应用到我的代码中。我可以识别代码中可能需要更改的部分。是否有任何 Java 专家能够查看我的代码并向我解释哪些方面是好的和坏的。我根
我有一个创建新对象 Student 并将其添加到数组列表 studentRegister 的方法: public void addStudent(String name, String age) {
在高耦合环境中,更改一个模块会影响另一个模块。好的,但我看不出这怎么可能(除了更改方法签名或返回类型)? 好吧,如果我改变一个类,那么它只能在以下情况下破坏其他类中的代码: 如果我突然改变了一个方法的
问题描述: 我正在一个项目中,以采用现有的JavaScript脚本并对其进行修改以支持异步加载。如果您不了解异步或延迟加载脚本,但想了解更多信息read this。 main.js脚本要做的第一件事之
我正在编写一个模拟,需要一些关于设计的提示。基本思想是生成给定随机过程的数据,然后将其用于各种计算。例如对于 1 次迭代: 进程 1 -> 为源 1 生成数据:x1 进程 2 -> 为源 1 生成数据
给定两个字符串,S1 和 S2。给定的计分方案包括空位罚分、不匹配分数和匹配分数。 找到与 S2 最匹配的 S1。 我的想法是列出所有可能的S1,然后与S2一一匹配。使用暴力列出所有可能的 S1。然后
我尝试使用 ctypes.CDLL 类 (Linux) 在 Python 中加载 C 共享库 .so。这是 link告诉我我做了什么。正如我看到的文档,它说 CDLL 类假定函数返回 int 类型。我
目录 什么是耦合性 什么是程序间的耦合 如何解耦 工厂模式解耦 案例 原因就是: 解决思路:
我尝试使用 Matlab 函数 Pdepe ( https://www.mathworks.com/help/matlab/ref/pdepe.html ) 求解平流扩散 react 问题的一维耦合偏
如何处理高级 C++ 应用程序中的耦合? 我们可以使用(例如)Witty 编写的 web 应用程序的完成代码,并用它制作控制台应用程序吗? ...或者将其更改为使用 Qt 制作的带有 GUI 的桌面应
假设我们有类: class Post def save # implementation end def self.find(id) #implementation e
简介 我正在尝试使用接口(interface)、抽象类和泛型在 Java 中创建一个相当复杂的结构。由于没有使用泛型的经验,在创建良好的 OOP 设计方面只有一般经验,这开始证明是一个相当大的挑战。
考虑 Windows 资源管理器(或 regedit 或类似工具)。左侧是 TreeView ,右侧是 ListView 。在我所知道的所有情况下,右 View 的内容都反射(reflect)了左 P
我有一个耦合代码(fortran 和 c++),我现在在 python 中调用。 main.exe 工作正常,但是当我在 python 中调用耦合版本时,出现段错误(核心转储)错误。我确定了出现问题的
我正在尝试编写 CMakeLists.txt 以耦合一个简单的 FORTRAN 程序,该程序使用 iso_c_binding 调用 C++ 函数。当我使用 gfortran 作为 FORTRAN 编译
我们将 NHibernate 用于 ORM,在程序的初始化阶段,我们需要从数据库中加载某个类 T 的许多实例。 在我们的应用程序中,提取所有这些实例的以下代码需要很长时间: public IList
我是一名优秀的程序员,十分优秀!