Just a few things inline

On Mon, Oct 5, 2015 at 7:21 PM, Dan Haywood <[email protected]>
wrote:

> On 4 Oct 2015 21:53, "Stephen Cameron" <[email protected]> wrote:
> >
> >
> > What I read from Martin Fowler is that a Mock framework, or that approach
> > in general, is different to traditional TDD in that it allows you to test
> > the behaviour of the system better.
> >
>
> The book I recommend to understand mocks is "Growing Object - Oriented
> Software", by Nat Pryce and Steve Freeman. These guys wrote JMock and
> developed many of the concepts. Mocking was Pryce's PhD thesis, IIRC. At
> any rate, if you read his writings he talks about mocks as being the
> mechanism by which the communication protocol between (usually, two)
> collaborators is documented /defined.
>
> Will give up on Fowler and go back to GOOS, which I did start to read. But
the example that they give is not a DI framework, so immediatly I am
struggling to equate to my situation.


> > What I perceive is that with a dependency injection framework, this
> > capability is limited, you can only pass a Mocked container to the first
> > object in a sequence easily, if that object calls other objects, which
> also
> > need to access the container for dependencies (e.g. domain services to
> > create new objects), then things are not simple.
>
> First point to make is that we only use mocks within unit tests, when we
> want to fake out all other parts of the system. For integration tests we
> don't do mocking at all.
>
> Second, when we do inject a mock, then we don't need to worry about the
> original implementation's own collaborators, so the point you raise is a
> non - issue.
>

The sequence of calls on the mock container to create the first object
(newTransientInstance, persistIfNotAlready, flush), works fine but if that
new object in turn creates more new objects, then no, as they don't know
anything about the mock, you've injected that dependancy into the first one
only. In my case there is a cascade of object creation newParticipant() may
trigger newParticipation() and newPerson(). So all I can do is create a
test for each of these methods (of domain services) individually and hope
that it all works in combination in an integration test, which is
reasonable I guess.

But my point is that the thing to mock is the DI container. The class
DomainObjectContainer isn't actually the DI 'container,' but a proxy, when
running a Junit test there is no true container, but there is its proxy
which we mock, its a subtle distinction.

Alternately I could just write all my repository factory methods as
(approximately):

if(container==null){
 return new MyDomainObject();
else
 return container.newTransientInstance(MyDomainObject.class);


> For example, suppose we inject an OrderRepository into a Customer entity,eg
> so that the Customer can query for old Orders. On the real implementation
> the OrderRepository will delegate in turn to the DomainObjectContainer, but
> in the unit test with the mock we don't care about that... we care only
> about the interaction between the Customer and the OrderRepository. We can
> therefore easily write unit tests for the case when there are no old
> Orders, or multiple old Orders, or whatever.
>
> Testing and documenting the interaction between two classes that you
stated above. I'll adopt that.


> > Regarding RAD, it seems that with an IDE you can design your object model
> > in the process of building your tests. If I define a sequence of
> > interations between objects (the message passing analogy) in my Mock test
> > sequence, then each new object method needed can be quickly added to the
> > respective object class definition.
> >
>
> Or an alternative, which we are thinking of using more and more, is to use
> contributed actions everywhere. See the incodehq/incode-module-note for an
> example... the actions on Note are actually all contributed actions, even
> though ask the functionality is in the same module.
>
> I'll write a separate email about this, in response to the RAD 2015 notes.


> > A nice programming workflow would seem to be: create the mocked
> sequences,
> > in the process define the object methods, implement the methods, with
> unit
> > tests as needed if involve complexity (over and above get/set)
> >
> > This seems to me to be fully TDD. When I write OO code without tests a
> UML
> > sequence diagram is mostly what I am thinking of, either a mental one or
> > one on paper. By adding Mocks I can speadily get this design into a coded
> > form as a mock test and then implement the details, its going from the
> big
> > picture down to the small. Without such an approach I would work the
> other
> > way, building upwards to get a complete working system, before being able
> > see, and refactor, the behaviour I want.
> >
>
> Yep, what you are describing is a lot like the GOOS book describes.
>
> > So, a question is: Is this already possible?
>
> It is, though I admit I don't find myself doing it in practice, at least
> not with Isis. Rather, I tend to prototype in order to experiment with
> different design ideas / object responsibilities, then rusty up and put the
> formal tests in later. If I can get away with just integ tests, then I
> do... but i use mocks and unit tests for any bits of code that are more
> algorithmic in nature.
>
>  You reload changed classes dynamically, that would be the difference.

Not sure what I describe above is best practice... there are risks in doing
> things that way, but it generally works out ok for me.
>

This is what I am trying to get a handle on, where do I start and stop with
TDD. That you see the most value from integ tests is valuable insight.

>
> > If not, then maybe the solution is to create something like the wrap
> > method, one that turns the Apache Isis DI container itself into a Mock
> > framework? At the minimum this would abstract all the datanucleus calls
> and
> > allow me to define the order of creation of all new objects as an
> > expectation.
> >
>
> Not sure I exactly follow, but in any case don't think it's needed.
>
> > A small question re the RAD Race (Dan/Jeroen), was the support for XLS
> > provided by Datanucleus not sufficient to use for loading of fixtures
> > directly from the spreadsheets? Maybe mapping was the problem?
> >
>
> We didn't explore that. However, as things are set up currently, DN had
> only one Store implementation, so one needs to choose between spreadsheet
> vs RDBMS. I suppose one could imagine some sort of federated Store
> implementation, but it seems like a lot of engineering just to be able to
> read a spreadsheet.
>


I currently have two Java domain models one in Isis and one generated via
JPA support in Eclipse for the old database schema, still not sure if this
was the best approach, but it is flexible I guess. But there is there is
always SQL.

>
> Hth, Dan.
>
> > Regards
> > Steve Cameron
>

Reply via email to