I have a framework Whiteboard
that encapsulates my business logic. I'm trying to keep my dependencies inverted and decoupled, so since Whiteboard
depends on a repository, it declares a protocol WhiteboardRepository
, and it expects clients that link against Whiteboard
to supply an implementation of WhiteboardRepository
.
You can see this in the screen shot below. Note also the WhiteboardTests
group, which includes a WhiteboardRepositoryTests
class along with a WhiteboardRepositoryFake
and its own test subclass.
To ensure that implementations of WhiteboardRepository
behave as expected, the WhiteboardTests
test bundle defines a WhiteboardRepositoryTests
subclass of XCTestCase
:
class WhiteboardRepositoryTests: XCTestCase {
var repo: WhiteboardRepository?
override func setUp() {
if let repo = repo {
// test setup here
}
}
// test cases here
}
In order for a client of Whiteboard
to test its implementation of WhiteboardRepository
, the test class for the implementation subclasses the WhiteboardRepositoryTests
and supplies an instance of the implementation to the test subclass, which then uses that instance when running the tests.
For example, here's what WhiteboardRepositoryFakeTests
looks like:
class WhiteboardRepositoryFakeTests: WhiteboardRepositoryTests {
override func setUp() {
repo = WhiteboardRepositoryFake()
super.setUp()
}
// the test classes run, using the instance of WhiteboardRepositoryFake()
}
This works fine, of course, since WhiteboardRepositoryFakeTests
is in the WhiteboardTests
bundle, so WhiteboardRepositoryTests
is exposed to WhiteboardRepositoryFakeTests
.
The problem is: apps that link against Whiteboard
will need to create their own subclass of WhiteboardRepositoryTests
to test their own implementation, but because they don't have access to the WhiteboardTests
test bundle, they're not aware of the WhiteboardRepositoryTests
class and so can't subclass it.
I've got multiple clients consuming Whiteboard
, so I can't simply copy the WhiteboardRepositoryTests
class into each client—and nor would I want to, since it's the responsibility of Whiteboard
to define WhiteboardRepository
's behavior, so WhiteboardRepositoryTests
should live in Whiteboard
's test bundle. In an ideal world, I'd be able to link or inject Whiteboard
's test bundle into a client's test bundle so that WhiteboardRepositoryTests
is exposed to the client's tests, but I don't see how I can do this.
Is there any way around this obstacle? How can I expose WhiteboardRepositoryTests
to tests within a client test bundle so that the client can make sure its implementation of WhiteboardRepository
behaves as expected?