Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's best way to mock objects in swift within XCTest?

What's best way to mock objects in swift within XCTest? Is it just define classes inside functions with required functionality? Or any better options exist?

like image 610
Danil Avatar asked Jul 02 '14 04:07

Danil


People also ask

What is mocking in unit testing Swift?

In automated tests, it is creating an object that conforms to the same behavior as the real object it is mocking. Many times the object you want to test has a dependency on an object that you have no control over. There are several ways to create iOS unit testing mock objects. One way is to subclass it.

What is a stub vs mock?

Stub: a dummy piece of code that lets the test run, but you don't care what happens to it. Substitutes for real working code. Mock: a dummy piece of code that you verify is called correctly as part of the test. Substitutes for real working code.

What is the goal of using mock object?

Using mock objects allows developers to focus their tests on the behavior of the system under test without worrying about its dependencies. For example, testing a complex algorithm based on multiple objects being in particular states can be clearly expressed using mock objects in place of real objects.

How do you mock a function in Swift?

Techniques for Mocking Swift Standalone FunctionsIf you call the function from a class, promote the function call to a method call. Override it in a test-specific subclass. If you call the function from a type that prevents subclassing, create a function with the same signature in your code.


1 Answers

I recommend using Cuckoo, which is similar to Mockito.

Example Classes:

class ExampleObject {

    var number: Int = 0

    func evaluate(number: Int) -> Bool {
        return self.number == number
    }

}

class ExampleChecker {

    func check(object: ExampleObject) -> Bool {
        return object.evaluate(5)
    }

}

Example Test:

@testable import App
import Cuckoo
import XCTest

class ExampleCheckerTests: XCTestCase {

    func testCheck() {
        // 1. Arrange
        let object = MockExampleObject().spy(on: ExampleObject())
        stub(object) { object in
            when(object.evaluate(any())).thenDoNothing()
        }
        let checker = ExampleChecker()

        // 2. Action
        checker.check(object)

        // 3. Assert
        _ = verify(object).number.get
        verify(object).evaluate(any())
        verifyNoMoreInteractions(object)
    }

}

Note that the MockExampleObject class is auto-generated using custom Run script (in Build Phases), which Cuckoo docs mentions (in their install section).

like image 82
sundance Avatar answered Sep 17 '22 17:09

sundance