在测试中模拟UIView扩展“ApiProtocol” - swift4

时间:2018-05-25 18:46:19

标签: swift swift3 protocols swift4 xctest

给定一个“注入”MyUIView的协议和扩展。 可以调用func Node并按预期返回“hello world”。

进行单元测试public Node addAtLast(Node head, int data) { if (head == null) { // handle adding the first Node return new Node(data); } Node temp = head; Node newNode = new Node(data); while (temp.next != null) { temp = temp.next; } temp.next = newNode; System.out.println(temp); return head; } 时需要在3种不同的测试中进行模拟。

最好的方法是什么?

协议&扩展

stubMePlease()

UIView“注入/扩展”ApiProtocol

stubMePlease()

测试课

protocol ApiProtocol {
    func stubMePlease() -> String
}

extension ApiProtocol {
    func stubMePlease() -> String {
        return "hello world"
    }
}

由于

1 个答案:

答案 0 :(得分:2)

您不应使用“扩展”来实现协议的功能,您应该使用它来扩展您的协议,即添加新功能。通常,您使用一些方便的方法重载来扩展自己的协议,并根据协议中的方法实现它们,以便实现相同协议的每个类都可以避免实现它们(同时客户端可以从重载中受益)。

首先,您需要实际执行协议:

class ApiProtocolForTests: ApiProtocol {
    func stubMePlease() -> String {
        return "fake hello world in test"
    }
}

class ApiProtocolForRealz: ApiProtocol {
    func stubMePlease() -> String {
        return "hello world in real life"
    }
}

然后在MyUIView中,而不是继承/实现ApiProtocol,这在概念上没有意义,你应该在init构造函数中传递它,例如:

class MyUIView: UIView {
    let api: ApiProtocol

    override init(frame: CGRect, api: ApiProtocol) {
        super.init(frame: frame)
        self.api = api
        foo()
    }
    ...

在测试中,您将通过为其提供ApiProtocolForTests版本的协议来创建MyUIView:myview = MyUIView(frame: frame, api: ApiProtocolForTests())

这也称为"injecting" a dependency“ApiProtocol”。