Last active
February 17, 2016 14:52
-
-
Save justanr/8261384d23d4a7b1d0ad to your computer and use it in GitHub Desktop.
Test Builder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from copy import deepcopy | |
class Builder(object): | |
def __init__(self, target, *args, **kwargs): | |
self._target = target | |
self._kwargs = kwargs | |
self._args = list(args) | |
def having(self, *args, **kwargs): | |
self._kwargs.update(kwargs) | |
self._args.extend(args) | |
return self | |
def from_(self, **kwargs): | |
built = {k: v.build() for k, v in kwargs.items()} | |
return self.having(**built) | |
def but(self): | |
args = deepcopy(self._args) | |
kwargs = deepcopy(self._kwargs) | |
return self.__class__(self._target, *args, **kwargs) | |
def build(self): | |
return self._target(*self._args, **self._kwargs) | |
def __getattr__(self, attr): | |
return getattr(self.build(), attr) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class DoesSomething(object): | |
def __init__(self, user, notifier): | |
self.user = user | |
self.notifier = notifier | |
def tell_user(self, msg): | |
self.notifier.notify(self.user, msg) | |
class User(object): | |
def __init__(self, name, email): | |
self.name = name | |
self.email = email | |
def __repr__(self): | |
return 'User(name={}, email={})'.format(self.name, self.email) | |
class Notifier(object): | |
def notify(self, sender, receiver, msg): | |
if receiver.name == sender.name: | |
raise ValueError("Can't send message to self.") | |
return "{0.name} telling {1.name} about {2}".format(sender, receiver, msg)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def test_build_user_with_defaults(): | |
u = Builder(User, name='jeff', email='jeffmail').build() | |
assert u.name == 'jeff' | |
assert u.email == 'jeffmail' | |
def test_but_overrides_already_provided_values(): | |
u = Builder(User, name='jeff', email='jeffmail').but().having(name='fred').build() | |
assert u.name == 'fred' | |
def test_from_adds_to_kwargs(): | |
sink = Builder(dict).from_(user=Builder(User, name='', email='')).build() | |
assert 'user' in sink | |
def test_something_complex(): | |
UserBuilder = Builder(User).having('jeff', 'jeffmail') | |
ds = Builder(DoesSomething).from_(user=UserBuilder).having(notifier=Notifier()).build() | |
ds.tell_user(UserBuilder.build(), 'hello') | |
DefaultUser = Builder(User, name='jeff', email='jeffmail') | |
def test_whatever(): | |
assert DefaultUser.name == 'jeff' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Given this sort of pattern is far more useful when you have value objects running all around.