The current plan is to have spell casting use effects sub-system and make Spell object a composite that has a list of effects. In order to make construction of Spells easy, I’m planning on using a factory and call it while creating the action. Following code captures this in the form of a test:
def test_spell_is_created_with_a_factory(self): """ When creating a spell casting action, spell should be created """ spell_factory = SpellFactoryBuilder().build() when(spell_factory).create_spell('healing wind').thenReturn(mock()) spellcasting_factory = (SpellCastingFactoryBuilder() .with_spell_factory(spell_factory) .build()) spellcasting_factory.get_action( SpellCastingParameters(self, direction = 1, spell_name = 'healing wind')) verify(spell_factory).create_spell('healing wind')
Essentially, when SpellCastingFactory is used to create a spell called “healing wind”, the SpellFactory should receive a call to make a spell called “healing wind”. I’m creating spell_factory with SpellFactoryBuilder (so I have a real instance and not just a mock object), but then I’m using mockito to tell it to return mock when create_spell – method is called. I would like to use mock, but for some reason I couldn’t get it working with the code in SpellCastingFactoryBuilder:
def with_spell_factory(self, spell_factory): """ Configure spell factory to use """ if spell_factory == None: self.use_real_spell_factory = True else: if hasattr(spell_factory, 'build'): self.spell_factory = spell_factory.build() else: self.spell_factory = spell_factory return self
When creating a SpellCastingFactory with the builder, I can supply it with a spell_factory to use. I the spell_factory has method “build”, it will be called and the result is used as a factory, otherwise the supplied object is used. For mock object, hasattr will always return True, so this approach does not work.
Following modification to code makes the test to pass:
@logged def get_action(self, parameters): """ Create a spell casting action :param parameters: parameters used to control creation :type parameters: SpellCastingParameters """ spell = self.spell_factory.create_spell(parameters.spell_name) return SpellCastingAction(caster = parameters.caster, direction = parameters.direction, spell = spell)
Again, really small step forward, but the progression is steady and the direction looks good. I’m going to leave details about finding who the spell hits and how much the mana is subtracted later (both probably ending up in the SpellCastingAction) and concentrate on getting the spell part done.
Code for the changes can be found in the following commit.