Discussion:
[GOOS] Testing Public Interface
Dariusz Gafka
2016-10-26 18:03:27 UTC
Permalink
Hello,

I am strugling with one problem about testing public interface only.

I think the best explanation will be, if I start with example. So here we
go :)

We are having

public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;

TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}

public void transfer(Money money, String type)
{
transactionProvider = this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}

class TransactionProviderFactory {

TransactionProvider getFor(String type) {
//returns for type
}
}


Now let's say they both belongs to the same package.

1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do something
else with it?

2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Israel Fonseca
2016-10-26 18:26:17 UTC
Permalink
1.a I would create a stub of TransactionProviderFactory that given a
certain type return a mock X, and verifying that the mock X calls the
startTransaction with the input money.
1.b I would reconsider the design of having the factory as the collaborator
of the TransactionService, and probably just having an TransactionProvider
as the only dependency. In that scenario the transfer() method wouldn't
receive the type also (I don't know if this is possible).

2. Don't redo those tests in the TransactionServiceTest. If you had to
handle the exception in the TransactionService, in that case you should
test this behaviour.
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here we
go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do something
else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dariusz Gafka
2016-10-26 18:59:27 UTC
Permalink
Thanks for your fast answer.

1b Well this is not possible. I can decide which transaction provider I use
only at the run time.

1a
If I am supposted to stub the TransactionProviderFactory my tests will
depend on existence of it. For example I will want to move the behaviour of
deciding which provider to choose somewhere else. I will have to not only
change creating of the Service, but also every test, related to transfer
method. Isn't there best way of handling it? Because my feeling goes for
just passing the real instance to the constructor, but from other side it
looks really bad to pass instance of stateless service instead like you
mentioned stubbing it.

2.
Well if I am supposted to test for exceptions from TransactionService and
have stub of TransactionProviderFactory, I will have to stub throwing
exception and also write tests for TransactionProviderFactory to proof,
that it for sure throws exception, when there is no specific type



W dniu środa, 26 października 2016 20:26:29 UTC+2 uÅŒytkownik Israel Fonseca
Post by Israel Fonseca
1.a I would create a stub of TransactionProviderFactory that given a
certain type return a mock X, and verifying that the mock X calls the
startTransaction with the input money.
1.b I would reconsider the design of having the factory as the
collaborator of the TransactionService, and probably just having an TransactionProvider
as the only dependency. In that scenario the transfer() method wouldn't
receive the type also (I don't know if this is possible).
2. Don't redo those tests in the TransactionServiceTest. If you had to
handle the exception in the TransactionService, in that case you should
test this behaviour.
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here we
go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do
something else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dariusz Gafka
2016-10-26 19:13:38 UTC
Permalink
Also I am curious what test cases could be used for minesweeper kata
<http://codingdojo.org/cgi-bin/index.pl?KataMinesweeper>.

So there would be a Game class, that accepts some board (array of arrays)
and returns new board with marked numbers.
Other classes would be internal ones and shouldn't be tested in my
understanding of doing TDD well.
But in this way the unit tests are becoming pretty large and are the same
as acceptance tests(!) for this game, which I guess is not correct

W dniu środa, 26 października 2016 20:59:27 UTC+2 uÅŒytkownik Dariusz Gafka
Post by Dariusz Gafka
Thanks for your fast answer.
1b Well this is not possible. I can decide which transaction provider I
use only at the run time.
1a
If I am supposted to stub the TransactionProviderFactory my tests will
depend on existence of it. For example I will want to move the behaviour of
deciding which provider to choose somewhere else. I will have to not only
change creating of the Service, but also every test, related to transfer
method. Isn't there best way of handling it? Because my feeling goes for
just passing the real instance to the constructor, but from other side it
looks really bad to pass instance of stateless service instead like you
mentioned stubbing it.
2.
Well if I am supposted to test for exceptions from TransactionService and
have stub of TransactionProviderFactory, I will have to stub throwing
exception and also write tests for TransactionProviderFactory to proof,
that it for sure throws exception, when there is no specific type
W dniu środa, 26 października 2016 20:26:29 UTC+2 uÅŒytkownik Israel
Post by Israel Fonseca
1.a I would create a stub of TransactionProviderFactory that given a
certain type return a mock X, and verifying that the mock X calls the
startTransaction with the input money.
1.b I would reconsider the design of having the factory as the
collaborator of the TransactionService, and probably just having an TransactionProvider
as the only dependency. In that scenario the transfer() method wouldn't
receive the type also (I don't know if this is possible).
2. Don't redo those tests in the TransactionServiceTest. If you had to
handle the exception in the TransactionService, in that case you should
test this behaviour.
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here
we go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do
something else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Matteo Vaccari
2016-10-26 19:39:50 UTC
Permalink
Hi Dariusz,

this example code does not seem to do much, now, does it? Perhaps the only
interesting thing that happens here is in the getFor() method, which you
didn't show. This looks to me like you came up with a solution, and you're
now trying to write tests that prove that your solution exists. Good tests
(IMO) are tests that talk about specific cases of business things that are
interesting to your customer.

A better approach (in my opinion) is to start with a blank slate: forget
about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that

How about you start with a test of what interesting things happen, from the
point of view of the business, when someone calls

transfer(new Money(1), "whatever")

Try to solve it in the simplest possible way, then proceed with the next
variation of

transfer(X, Y)

that makes sense to the business. Don't write more code than is required
to pass the tests. Let the tests guide you.

Hope this helps,

Matteo
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here we
go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider = this.transactionProviderFactory.
getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do something
else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Israel Fonseca
2016-10-26 21:28:50 UTC
Permalink
Round 2 :)

1.a Maybe I didn't get it right, but if you use a real instance it won't
solve the problem of having to change all the tests in the case that you
figure out that you don't need the factory anymore. When you say: "my tests
will depend on existence of it" as a bad thing, I don't agree. You are
testing a class that depends on another collaborators and makes sense to
the test express this necessity somehow (you have to give a
real/fake/stub/mock implementation to it). By having to handle this
dependency in your test, the test is also giving some feedback about your
design (when you happen to have 5+ collaborators you will think "man,
there's something wrong in here").

2. In that case, yes, I would create a test to check if my TransactionService
handles the failure accordingly (write some log file), and for that I would
stub the collaborator to throw an exception and check the logging (and yes,
It'll be like a repeated test, but one case if for identifying an error and
the other is about how to handle the error).

I recommend the following video, could give you some insights about testing:

https://vimeo.com/80533536
Post by Matteo Vaccari
Hi Dariusz,
this example code does not seem to do much, now, does it? Perhaps the
only interesting thing that happens here is in the getFor() method, which
you didn't show. This looks to me like you came up with a solution, and
you're now trying to write tests that prove that your solution exists.
Good tests (IMO) are tests that talk about specific cases of business
things that are interesting to your customer.
A better approach (in my opinion) is to start with a blank slate: forget
about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that
How about you start with a test of what interesting things happen, from
the point of view of the business, when someone calls
transfer(new Money(1), "whatever")
Try to solve it in the simplest possible way, then proceed with the next
variation of
transfer(X, Y)
that makes sense to the business. Don't write more code than is required
to pass the tests. Let the tests guide you.
Hope this helps,
Matteo
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here we
go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do something
else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dariusz Gafka
2016-10-27 06:19:30 UTC
Permalink
@Israel
I understand your point of view, because I always do the same. But I just
feel there is way to improve it and I am trying to find that way. :)
Doing TDD by the book as far as I understand would be in this way:
Red -> write the failing test
Green -> make it pass
Refactor -> On this stage I should be able to refactor the code without
changing the tests. Let's say I want to get rid off
TransactionProviderFactory and implement it differently. If I stub it I
will have to change the tests, which shouldn't be changed.

@Matteo
After some time of thinking, you're right in here. I came with the solution
first even that I wrote the tests first. I know, that is not way to do it,
but the experience and habits are just strong. When I start to thinking of
some problem, my brain tries to find solution immediately.
So "Let the tests guide you." isn't so simple, like it sounds. :)

W dniu środa, 26 października 2016 23:29:10 UTC+2 uÅŒytkownik Israel Fonseca
Post by Israel Fonseca
Round 2 :)
1.a Maybe I didn't get it right, but if you use a real instance it won't
solve the problem of having to change all the tests in the case that you
figure out that you don't need the factory anymore. When you say: "my
tests will depend on existence of it" as a bad thing, I don't agree. You
are testing a class that depends on another collaborators and makes sense
to the test express this necessity somehow (you have to give a
real/fake/stub/mock implementation to it). By having to handle this
dependency in your test, the test is also giving some feedback about your
design (when you happen to have 5+ collaborators you will think "man,
there's something wrong in here").
2. In that case, yes, I would create a test to check if my TransactionService
handles the failure accordingly (write some log file), and for that I would
stub the collaborator to throw an exception and check the logging (and yes,
It'll be like a repeated test, but one case if for identifying an error and
the other is about how to handle the error).
https://vimeo.com/80533536
Post by Matteo Vaccari
Hi Dariusz,
this example code does not seem to do much, now, does it? Perhaps the
only interesting thing that happens here is in the getFor() method, which
you didn't show. This looks to me like you came up with a solution, and
you're now trying to write tests that prove that your solution exists.
Good tests (IMO) are tests that talk about specific cases of business
things that are interesting to your customer.
A better approach (in my opinion) is to start with a blank slate: forget
about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that
How about you start with a test of what interesting things happen, from
the point of view of the business, when someone calls
transfer(new Money(1), "whatever")
Try to solve it in the simplest possible way, then proceed with the next
variation of
transfer(X, Y)
that makes sense to the business. Don't write more code than is required
to pass the tests. Let the tests guide you.
Hope this helps,
Matteo
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here
we go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do
something else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Matteo Vaccari
2016-10-27 06:28:25 UTC
Permalink
Post by Dariusz Gafka
@Matteo
After some time of thinking, you're right in here. I came with the
solution first even that I wrote the tests first. I know, that is not way
to do it, but the experience and habits are just strong. When I start to
thinking of some problem, my brain tries to find solution immediately.
So "Let the tests guide you." isn't so simple, like it sounds. :)
You are right, "Let the tests guide you" is not easy! You may at first
treat it like a game with simple rules: don't write more code than is
needed to pass hte test. Focus on the process, not on your deadline. It may
be easier to do that on a kata rather than on real work :)

The video training by JB Rainsberger is quite good:
http://online-training.jbrains.ca/p/wbitdd-01

Matteo
Post by Dariusz Gafka
W dniu środa, 26 października 2016 23:29:10 UTC+2 uÅŒytkownik Israel
Post by Israel Fonseca
Round 2 :)
1.a Maybe I didn't get it right, but if you use a real instance it won't
solve the problem of having to change all the tests in the case that you
figure out that you don't need the factory anymore. When you say: "my
tests will depend on existence of it" as a bad thing, I don't agree. You
are testing a class that depends on another collaborators and makes sense
to the test express this necessity somehow (you have to give a
real/fake/stub/mock implementation to it). By having to handle this
dependency in your test, the test is also giving some feedback about your
design (when you happen to have 5+ collaborators you will think "man,
there's something wrong in here").
2. In that case, yes, I would create a test to check if my TransactionService
handles the failure accordingly (write some log file), and for that I would
stub the collaborator to throw an exception and check the logging (and yes,
It'll be like a repeated test, but one case if for identifying an error and
the other is about how to handle the error).
https://vimeo.com/80533536
Post by Matteo Vaccari
Hi Dariusz,
this example code does not seem to do much, now, does it? Perhaps the
only interesting thing that happens here is in the getFor() method, which
you didn't show. This looks to me like you came up with a solution, and
you're now trying to write tests that prove that your solution exists.
Good tests (IMO) are tests that talk about specific cases of business
things that are interesting to your customer.
A better approach (in my opinion) is to start with a blank slate: forget
about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that
How about you start with a test of what interesting things happen, from
the point of view of the business, when someone calls
transfer(new Money(1), "whatever")
Try to solve it in the simplest possible way, then proceed with the next
variation of
transfer(X, Y)
that makes sense to the business. Don't write more code than is
required to pass the tests. Let the tests guide you.
Hope this helps,
Matteo
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here
we go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider = this.transactionProviderFactor
y.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do
something else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not
existing TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
com.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
com.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Israel Fonseca
2016-10-27 08:44:25 UTC
Permalink
@Darius
Now I got your point. From my experience: If you choose the path of
Mocking/Interaction testing, you can't avoid this kind of coupling with the
test implementation, In this case you may use this over-constraining as an
advantage to check if your test is being to hard to build (in that case
your SUT may be to big). This design upfront thing that @Matteo warned you
about, indeed can be a dangerous thing, but it could no too (vague answer.
:P). JBrains and Sandro mancuso talk about this in here:


To have the advantage to really be able to refactor freely (besides changes
in the constructor), only with the Classist Approach of using the real
implementation on an alternate in-memory implementation (like Uncle Bob
does). But this path come with it's own 'problems': fixtures that can be
are hard to setup, maintaining another implementation of your collaborators
(like an ProductRepositoryInMemory) and being a harder to implement you app
in a top-bottom fashion.

I spent lot of time doing both and in the end I think it's matter of taste,
you have to choose the technique that fits your 'way of programming'
Post by Dariusz Gafka
@Matteo
After some time of thinking, you're right in here. I came with the
solution first even that I wrote the tests first. I know, that is not way
to do it, but the experience and habits are just strong. When I start to
thinking of some problem, my brain tries to find solution immediately.
So "Let the tests guide you." isn't so simple, like it sounds. :)
You are right, "Let the tests guide you" is not easy! You may at first
treat it like a game with simple rules: don't write more code than is
needed to pass hte test. Focus on the process, not on your deadline. It may
be easier to do that on a kata rather than on real work :)
http://online-training.jbrains.ca/p/wbitdd-01
Matteo
W dniu środa, 26 października 2016 23:29:10 UTC+2 uÅŒytkownik Israel
Round 2 :)
1.a Maybe I didn't get it right, but if you use a real instance it won't
solve the problem of having to change all the tests in the case that you
figure out that you don't need the factory anymore. When you say: "my
tests will depend on existence of it" as a bad thing, I don't agree. You
are testing a class that depends on another collaborators and makes sense
to the test express this necessity somehow (you have to give a
real/fake/stub/mock implementation to it). By having to handle this
dependency in your test, the test is also giving some feedback about your
design (when you happen to have 5+ collaborators you will think "man,
there's something wrong in here").
2. In that case, yes, I would create a test to check if my TransactionService
handles the failure accordingly (write some log file), and for that I would
stub the collaborator to throw an exception and check the logging (and yes,
It'll be like a repeated test, but one case if for identifying an error and
the other is about how to handle the error).
https://vimeo.com/80533536
Hi Dariusz,
this example code does not seem to do much, now, does it? Perhaps the
only interesting thing that happens here is in the getFor() method, which
you didn't show. This looks to me like you came up with a solution, and
you're now trying to write tests that prove that your solution exists.
Good tests (IMO) are tests that talk about specific cases of business
things that are interesting to your customer.
A better approach (in my opinion) is to start with a blank slate: forget
about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that
How about you start with a test of what interesting things happen, from
the point of view of the business, when someone calls
transfer(new Money(1), "whatever")
Try to solve it in the simplest possible way, then proceed with the next
variation of
transfer(X, Y)
that makes sense to the business. Don't write more code than is required
to pass the tests. Let the tests guide you.
Hope this helps,
Matteo
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here we
go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do something
else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Matteo Vaccari
2016-10-27 09:55:55 UTC
Permalink
Hi Israel,

IMO it's not a matter of "choosing a path" between using mocks or not using
them. They are one tool out of several.

Usually I start with the business requirements, and list the tests that I
think are needed to meet those requirements. Then I write the first test
and start the TDD process. In the course of doing this, I write more
tests, and sometimes I find that some tests are too hard to write, or too
hard to pass. Then I have to think and probably change the design. The
style of test that I use depends on the context. I always try to make the
test tell a story about what I'm trying to do. Sometimes mocks help me do
that, sometimes I use other techniques.

When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain. You
should not expect to find the right abstractions easily! It generally
takes more than one try. Once you have found a good abstraction, it tends
to be stable. It may help to live with duplication for some time before
you start abstracting.

Hope this helps!

Matteo
Post by Israel Fonseca
@Darius
Now I got your point. From my experience: If you choose the path of
Mocking/Interaction testing, you can't avoid this kind of coupling with the
test implementation, In this case you may use this over-constraining as an
advantage to check if your test is being to hard to build (in that case
about, indeed can be a dangerous thing, but it could no too (vague answer.
http://youtu.be/ty3p5VDcoOI
To have the advantage to really be able to refactor freely (besides
changes in the constructor), only with the Classist Approach of using the
real implementation on an alternate in-memory implementation (like Uncle
Bob does). But this path come with it's own 'problems': fixtures that can
be are hard to setup, maintaining another implementation of your
collaborators (like an ProductRepositoryInMemory) and being a harder to
implement you app in a top-bottom fashion.
I spent lot of time doing both and in the end I think it's matter of
taste, you have to choose the technique that fits your 'way of programming'
Em qui, 27 de out de 2016 às 04:28, Matteo Vaccari <
Post by Dariusz Gafka
@Matteo
After some time of thinking, you're right in here. I came with the
solution first even that I wrote the tests first. I know, that is not way
to do it, but the experience and habits are just strong. When I start to
thinking of some problem, my brain tries to find solution immediately.
So "Let the tests guide you." isn't so simple, like it sounds. :)
You are right, "Let the tests guide you" is not easy! You may at first
treat it like a game with simple rules: don't write more code than is
needed to pass hte test. Focus on the process, not on your deadline. It may
be easier to do that on a kata rather than on real work :)
http://online-training.jbrains.ca/p/wbitdd-01
Matteo
W dniu środa, 26 października 2016 23:29:10 UTC+2 uÅŒytkownik Israel
Round 2 :)
1.a Maybe I didn't get it right, but if you use a real instance it won't
solve the problem of having to change all the tests in the case that you
figure out that you don't need the factory anymore. When you say: "my
tests will depend on existence of it" as a bad thing, I don't agree. You
are testing a class that depends on another collaborators and makes sense
to the test express this necessity somehow (you have to give a
real/fake/stub/mock implementation to it). By having to handle this
dependency in your test, the test is also giving some feedback about your
design (when you happen to have 5+ collaborators you will think "man,
there's something wrong in here").
2. In that case, yes, I would create a test to check if my TransactionService
handles the failure accordingly (write some log file), and for that I would
stub the collaborator to throw an exception and check the logging (and yes,
It'll be like a repeated test, but one case if for identifying an error and
the other is about how to handle the error).
https://vimeo.com/80533536
Hi Dariusz,
this example code does not seem to do much, now, does it? Perhaps the
only interesting thing that happens here is in the getFor() method, which
you didn't show. This looks to me like you came up with a solution, and
you're now trying to write tests that prove that your solution exists.
Good tests (IMO) are tests that talk about specific cases of business
things that are interesting to your customer.
A better approach (in my opinion) is to start with a blank slate: forget
about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that
How about you start with a test of what interesting things happen, from
the point of view of the business, when someone calls
transfer(new Money(1), "whatever")
Try to solve it in the simplest possible way, then proceed with the next
variation of
transfer(X, Y)
that makes sense to the business. Don't write more code than is required
to pass the tests. Let the tests guide you.
Hope this helps,
Matteo
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here we
go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider = this.transactionProviderFactory.
getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do
something else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dariusz Gafka
2016-10-27 10:57:51 UTC
Permalink
@Israel
Is Uncle Bob really using in memory implementations for unit testing?
This is really weird thing to me, because in my opinion unit tests are not
place for in memory implementations. I use them for acceptance tests only
written in gherkin.

@Matteo

"When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain"
Do you mean, that when we find correct abstraction for the domain, we will
no need to change interaction between two objects while refactoring?
What about situation when the abstraction is correct, but we would like to
delegate it to some other place (it will break the tests)?


I would love to see some of your code examples with tests, to better
understand your way of thinking.


W dniu czwartek, 27 października 2016 11:56:38 UTC+2 uŌytkownik Matteo
Post by Matteo Vaccari
Hi Israel,
IMO it's not a matter of "choosing a path" between using mocks or not
using them. They are one tool out of several.
Usually I start with the business requirements, and list the tests that I
think are needed to meet those requirements. Then I write the first test
and start the TDD process. In the course of doing this, I write more
tests, and sometimes I find that some tests are too hard to write, or too
hard to pass. Then I have to think and probably change the design. The
style of test that I use depends on the context. I always try to make the
test tell a story about what I'm trying to do. Sometimes mocks help me do
that, sometimes I use other techniques.
When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain. You
should not expect to find the right abstractions easily! It generally
takes more than one try. Once you have found a good abstraction, it tends
to be stable. It may help to live with duplication for some time before
you start abstracting.
Hope this helps!
Matteo
Post by Israel Fonseca
@Darius
Now I got your point. From my experience: If you choose the path of
Mocking/Interaction testing, you can't avoid this kind of coupling with the
test implementation, In this case you may use this over-constraining as an
advantage to check if your test is being to hard to build (in that case
about, indeed can be a dangerous thing, but it could no too (vague answer.
http://youtu.be/ty3p5VDcoOI
To have the advantage to really be able to refactor freely (besides
changes in the constructor), only with the Classist Approach of using the
real implementation on an alternate in-memory implementation (like Uncle
Bob does). But this path come with it's own 'problems': fixtures that can
be are hard to setup, maintaining another implementation of your
collaborators (like an ProductRepositoryInMemory) and being a harder to
implement you app in a top-bottom fashion.
I spent lot of time doing both and in the end I think it's matter of
taste, you have to choose the technique that fits your 'way of programming'
Post by Matteo Vaccari
Post by Dariusz Gafka
@Matteo
After some time of thinking, you're right in here. I came with the
solution first even that I wrote the tests first. I know, that is not way
to do it, but the experience and habits are just strong. When I start to
thinking of some problem, my brain tries to find solution immediately.
So "Let the tests guide you." isn't so simple, like it sounds. :)
You are right, "Let the tests guide you" is not easy! You may at first
treat it like a game with simple rules: don't write more code than is
needed to pass hte test. Focus on the process, not on your deadline. It may
be easier to do that on a kata rather than on real work :)
http://online-training.jbrains.ca/p/wbitdd-01
Matteo
Post by Dariusz Gafka
W dniu środa, 26 października 2016 23:29:10 UTC+2 uÅŒytkownik Israel
Post by Israel Fonseca
Round 2 :)
1.a Maybe I didn't get it right, but if you use a real instance it
won't solve the problem of having to change all the tests in the case that
you figure out that you don't need the factory anymore. When you say: "my
tests will depend on existence of it" as a bad thing, I don't agree. You
are testing a class that depends on another collaborators and makes sense
to the test express this necessity somehow (you have to give a
real/fake/stub/mock implementation to it). By having to handle this
dependency in your test, the test is also giving some feedback about your
design (when you happen to have 5+ collaborators you will think "man,
there's something wrong in here").
2. In that case, yes, I would create a test to check if my TransactionService
handles the failure accordingly (write some log file), and for that I would
stub the collaborator to throw an exception and check the logging (and yes,
It'll be like a repeated test, but one case if for identifying an error and
the other is about how to handle the error).
https://vimeo.com/80533536
Em qua, 26 de out de 2016 às 17:40, Matteo Vaccari <
Post by Matteo Vaccari
Hi Dariusz,
this example code does not seem to do much, now, does it? Perhaps
the only interesting thing that happens here is in the getFor() method,
which you didn't show. This looks to me like you came up with a solution,
and you're now trying to write tests that prove that your solution exists.
Good tests (IMO) are tests that talk about specific cases of business
things that are interesting to your customer.
forget about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that
How about you start with a test of what interesting things happen,
from the point of view of the business, when someone calls
transfer(new Money(1), "whatever")
Try to solve it in the simplest possible way, then proceed with the
next variation of
transfer(X, Y)
that makes sense to the business. Don't write more code than is
required to pass the tests. Let the tests guide you.
Hope this helps,
Matteo
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So
here we go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that
is exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do
something else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not
existing TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Israel Fonseca
2016-10-27 11:18:17 UTC
Permalink
@Matteo
I agree with that, these techniques are tools and we have to be able to
choose the right tool for the task in hand. My phrasing didn't get right. :)

@Darius
I'm pretty sure that I saw this approach in this series:
https://cleancoders.com/videos/java-case-study. And besides that, that's
the main point of his famous story about how the Fitnesse framework started
with an in-memory database for testing and in the end they figured that
they didn't need a 'real' database at all. Extra advice: if you have time
search for 'Functional Core, Imperative Shell' as another strategy to
design/test your application (I'm studying about it now).
Post by Dariusz Gafka
@Israel
Is Uncle Bob really using in memory implementations for unit testing?
This is really weird thing to me, because in my opinion unit tests are not
place for in memory implementations. I use them for acceptance tests only
written in gherkin.
@Matteo
"When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain"
Do you mean, that when we find correct abstraction for the domain, we will
no need to change interaction between two objects while refactoring?
What about situation when the abstraction is correct, but we would like to
delegate it to some other place (it will break the tests)?
I would love to see some of your code examples with tests, to better
understand your way of thinking.
W dniu czwartek, 27 października 2016 11:56:38 UTC+2 uŌytkownik Matteo
Hi Israel,
IMO it's not a matter of "choosing a path" between using mocks or not
using them. They are one tool out of several.
Usually I start with the business requirements, and list the tests that I
think are needed to meet those requirements. Then I write the first test
and start the TDD process. In the course of doing this, I write more
tests, and sometimes I find that some tests are too hard to write, or too
hard to pass. Then I have to think and probably change the design. The
style of test that I use depends on the context. I always try to make the
test tell a story about what I'm trying to do. Sometimes mocks help me do
that, sometimes I use other techniques.
When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain. You
should not expect to find the right abstractions easily! It generally
takes more than one try. Once you have found a good abstraction, it tends
to be stable. It may help to live with duplication for some time before
you start abstracting.
Hope this helps!
Matteo
@Darius
Now I got your point. From my experience: If you choose the path of
Mocking/Interaction testing, you can't avoid this kind of coupling with the
test implementation, In this case you may use this over-constraining as an
advantage to check if your test is being to hard to build (in that case
about, indeed can be a dangerous thing, but it could no too (vague answer.
http://youtu.be/ty3p5VDcoOI
To have the advantage to really be able to refactor freely (besides
changes in the constructor), only with the Classist Approach of using the
real implementation on an alternate in-memory implementation (like Uncle
Bob does). But this path come with it's own 'problems': fixtures that can
be are hard to setup, maintaining another implementation of your
collaborators (like an ProductRepositoryInMemory) and being a harder to
implement you app in a top-bottom fashion.
I spent lot of time doing both and in the end I think it's matter of
taste, you have to choose the technique that fits your 'way of programming'
@Matteo
After some time of thinking, you're right in here. I came with the
solution first even that I wrote the tests first. I know, that is not way
to do it, but the experience and habits are just strong. When I start to
thinking of some problem, my brain tries to find solution immediately.
So "Let the tests guide you." isn't so simple, like it sounds. :)
You are right, "Let the tests guide you" is not easy! You may at first
treat it like a game with simple rules: don't write more code than is
needed to pass hte test. Focus on the process, not on your deadline. It may
be easier to do that on a kata rather than on real work :)
http://online-training.jbrains.ca/p/wbitdd-01
Matteo
W dniu środa, 26 października 2016 23:29:10 UTC+2 uÅŒytkownik Israel
Round 2 :)
1.a Maybe I didn't get it right, but if you use a real instance it won't
solve the problem of having to change all the tests in the case that you
figure out that you don't need the factory anymore. When you say: "my
tests will depend on existence of it" as a bad thing, I don't agree. You
are testing a class that depends on another collaborators and makes sense
to the test express this necessity somehow (you have to give a
real/fake/stub/mock implementation to it). By having to handle this
dependency in your test, the test is also giving some feedback about your
design (when you happen to have 5+ collaborators you will think "man,
there's something wrong in here").
2. In that case, yes, I would create a test to check if my TransactionService
handles the failure accordingly (write some log file), and for that I would
stub the collaborator to throw an exception and check the logging (and yes,
It'll be like a repeated test, but one case if for identifying an error and
the other is about how to handle the error).
https://vimeo.com/80533536
Hi Dariusz,
this example code does not seem to do much, now, does it? Perhaps the
only interesting thing that happens here is in the getFor() method, which
you didn't show. This looks to me like you came up with a solution, and
you're now trying to write tests that prove that your solution exists.
Good tests (IMO) are tests that talk about specific cases of business
things that are interesting to your customer.
A better approach (in my opinion) is to start with a blank slate: forget
about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that
How about you start with a test of what interesting things happen, from
the point of view of the business, when someone calls
transfer(new Money(1), "whatever")
Try to solve it in the simplest possible way, then proceed with the next
variation of
transfer(X, Y)
that makes sense to the business. Don't write more code than is required
to pass the tests. Let the tests guide you.
Hope this helps,
Matteo
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here we
go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do something
else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Matteo Vaccari
2016-10-27 11:39:12 UTC
Permalink
Post by Dariusz Gafka
"When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain"
Do you mean, that when we find correct abstraction for the domain, we will
no need to change interaction between two objects while refactoring?
What about situation when the abstraction is correct, but we would like to
delegate it to some other place (it will break the tests)?
Nothing ever is perfect; you will always have some breakage when things
evolve. If the breakage is massive, then you probably have too much
duplication.


I would love to see some of your code examples with tests, to better
Post by Dariusz Gafka
understand your way of thinking.
This is a sequence of exercises that I wrote to specifically show how to
keep technical and boilerplate code to the minimum when doing a web
application:

https://github.com/xpmatteo/simple-design-in-action

One of my friends is using them in boot-camp training for new hires. I'm
not sure it will answer your questions, but at least it shows which
questions are important to me :)

Matteo
Post by Dariusz Gafka
@Israel
Is Uncle Bob really using in memory implementations for unit testing?
This is really weird thing to me, because in my opinion unit tests are not
place for in memory implementations. I use them for acceptance tests only
written in gherkin.
@Matteo
"When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain"
Do you mean, that when we find correct abstraction for the domain, we will
no need to change interaction between two objects while refactoring?
What about situation when the abstraction is correct, but we would like to
delegate it to some other place (it will break the tests)?
I would love to see some of your code examples with tests, to better
understand your way of thinking.
W dniu czwartek, 27 października 2016 11:56:38 UTC+2 uŌytkownik Matteo
Post by Matteo Vaccari
Hi Israel,
IMO it's not a matter of "choosing a path" between using mocks or not
using them. They are one tool out of several.
Usually I start with the business requirements, and list the tests that I
think are needed to meet those requirements. Then I write the first test
and start the TDD process. In the course of doing this, I write more
tests, and sometimes I find that some tests are too hard to write, or too
hard to pass. Then I have to think and probably change the design. The
style of test that I use depends on the context. I always try to make the
test tell a story about what I'm trying to do. Sometimes mocks help me do
that, sometimes I use other techniques.
When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain. You
should not expect to find the right abstractions easily! It generally
takes more than one try. Once you have found a good abstraction, it tends
to be stable. It may help to live with duplication for some time before
you start abstracting.
Hope this helps!
Matteo
Post by Israel Fonseca
@Darius
Now I got your point. From my experience: If you choose the path of
Mocking/Interaction testing, you can't avoid this kind of coupling with the
test implementation, In this case you may use this over-constraining as an
advantage to check if your test is being to hard to build (in that case
about, indeed can be a dangerous thing, but it could no too (vague answer.
http://youtu.be/ty3p5VDcoOI
To have the advantage to really be able to refactor freely (besides
changes in the constructor), only with the Classist Approach of using the
real implementation on an alternate in-memory implementation (like Uncle
Bob does). But this path come with it's own 'problems': fixtures that can
be are hard to setup, maintaining another implementation of your
collaborators (like an ProductRepositoryInMemory) and being a harder to
implement you app in a top-bottom fashion.
I spent lot of time doing both and in the end I think it's matter of
taste, you have to choose the technique that fits your 'way of programming'
Post by Matteo Vaccari
Post by Dariusz Gafka
@Matteo
After some time of thinking, you're right in here. I came with the
solution first even that I wrote the tests first. I know, that is not way
to do it, but the experience and habits are just strong. When I start to
thinking of some problem, my brain tries to find solution immediately.
So "Let the tests guide you." isn't so simple, like it sounds. :)
You are right, "Let the tests guide you" is not easy! You may at first
treat it like a game with simple rules: don't write more code than is
needed to pass hte test. Focus on the process, not on your deadline. It may
be easier to do that on a kata rather than on real work :)
http://online-training.jbrains.ca/p/wbitdd-01
Matteo
Post by Dariusz Gafka
W dniu środa, 26 października 2016 23:29:10 UTC+2 uÅŒytkownik Israel
Post by Israel Fonseca
Round 2 :)
1.a Maybe I didn't get it right, but if you use a real instance it
won't solve the problem of having to change all the tests in the case that
you figure out that you don't need the factory anymore. When you say: "my
tests will depend on existence of it" as a bad thing, I don't agree. You
are testing a class that depends on another collaborators and makes sense
to the test express this necessity somehow (you have to give a
real/fake/stub/mock implementation to it). By having to handle this
dependency in your test, the test is also giving some feedback about your
design (when you happen to have 5+ collaborators you will think "man,
there's something wrong in here").
2. In that case, yes, I would create a test to check if my TransactionService
handles the failure accordingly (write some log file), and for that I would
stub the collaborator to throw an exception and check the logging (and yes,
It'll be like a repeated test, but one case if for identifying an error and
the other is about how to handle the error).
https://vimeo.com/80533536
Em qua, 26 de out de 2016 às 17:40, Matteo Vaccari <
Post by Matteo Vaccari
Hi Dariusz,
this example code does not seem to do much, now, does it? Perhaps
the only interesting thing that happens here is in the getFor() method,
which you didn't show. This looks to me like you came up with a solution,
and you're now trying to write tests that prove that your solution exists.
Good tests (IMO) are tests that talk about specific cases of business
things that are interesting to your customer.
forget about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that
How about you start with a test of what interesting things happen,
from the point of view of the business, when someone calls
transfer(new Money(1), "whatever")
Try to solve it in the simplest possible way, then proceed with the
next variation of
transfer(X, Y)
that makes sense to the business. Don't write more code than is
required to pass the tests. Let the tests guide you.
Hope this helps,
Matteo
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So
here we go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory =
transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider = this.transactionProviderFactor
y.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that
is exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do
something else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not
existing TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to growing-object-oriented-softwa
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to growing-object-oriented-softwa
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to growing-object-oriented-softwa
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to growing-object-oriented-softwa
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
m.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dariusz Gafka
2016-10-28 04:56:32 UTC
Permalink
Seems, that there is no golden rule here (And I wish there would be one :)).
I will have to spend some time on testing both of ways. So I can find the
proper usage context for each one.

Anyways thanks for all your answers :)


W dniu czwartek, 27 października 2016 13:39:45 UTC+2 uŌytkownik Matteo
Post by Dariusz Gafka
"When mocks get in the way of refactoring, it usually happens because I'm
Post by Dariusz Gafka
mocking an interface that is not a good abstraction for the domain"
Do you mean, that when we find correct abstraction for the domain, we
will no need to change interaction between two objects while refactoring?
What about situation when the abstraction is correct, but we would like
to delegate it to some other place (it will break the tests)?
Nothing ever is perfect; you will always have some breakage when things
evolve. If the breakage is massive, then you probably have too much
duplication.
I would love to see some of your code examples with tests, to better
Post by Dariusz Gafka
understand your way of thinking.
This is a sequence of exercises that I wrote to specifically show how to
keep technical and boilerplate code to the minimum when doing a web
https://github.com/xpmatteo/simple-design-in-action
One of my friends is using them in boot-camp training for new hires. I'm
not sure it will answer your questions, but at least it shows which
questions are important to me :)
Matteo
Post by Dariusz Gafka
@Israel
Is Uncle Bob really using in memory implementations for unit testing?
This is really weird thing to me, because in my opinion unit tests are
not place for in memory implementations. I use them for acceptance tests
only written in gherkin.
@Matteo
"When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain"
Do you mean, that when we find correct abstraction for the domain, we
will no need to change interaction between two objects while refactoring?
What about situation when the abstraction is correct, but we would like
to delegate it to some other place (it will break the tests)?
I would love to see some of your code examples with tests, to better
understand your way of thinking.
W dniu czwartek, 27 października 2016 11:56:38 UTC+2 uŌytkownik Matteo
Post by Matteo Vaccari
Hi Israel,
IMO it's not a matter of "choosing a path" between using mocks or not
using them. They are one tool out of several.
Usually I start with the business requirements, and list the tests that
I think are needed to meet those requirements. Then I write the first test
and start the TDD process. In the course of doing this, I write more
tests, and sometimes I find that some tests are too hard to write, or too
hard to pass. Then I have to think and probably change the design. The
style of test that I use depends on the context. I always try to make the
test tell a story about what I'm trying to do. Sometimes mocks help me do
that, sometimes I use other techniques.
When mocks get in the way of refactoring, it usually happens because I'm
mocking an interface that is not a good abstraction for the domain. You
should not expect to find the right abstractions easily! It generally
takes more than one try. Once you have found a good abstraction, it tends
to be stable. It may help to live with duplication for some time before
you start abstracting.
Hope this helps!
Matteo
Post by Israel Fonseca
@Darius
Now I got your point. From my experience: If you choose the path of
Mocking/Interaction testing, you can't avoid this kind of coupling with the
test implementation, In this case you may use this over-constraining as an
advantage to check if your test is being to hard to build (in that case
about, indeed can be a dangerous thing, but it could no too (vague answer.
http://youtu.be/ty3p5VDcoOI
To have the advantage to really be able to refactor freely (besides
changes in the constructor), only with the Classist Approach of using the
real implementation on an alternate in-memory implementation (like Uncle
Bob does). But this path come with it's own 'problems': fixtures that can
be are hard to setup, maintaining another implementation of your
collaborators (like an ProductRepositoryInMemory) and being a harder to
implement you app in a top-bottom fashion.
I spent lot of time doing both and in the end I think it's matter of
taste, you have to choose the technique that fits your 'way of programming'
Em qui, 27 de out de 2016 às 04:28, Matteo Vaccari <
Post by Matteo Vaccari
Post by Dariusz Gafka
@Matteo
After some time of thinking, you're right in here. I came with the
solution first even that I wrote the tests first. I know, that is not way
to do it, but the experience and habits are just strong. When I start to
thinking of some problem, my brain tries to find solution immediately.
So "Let the tests guide you." isn't so simple, like it sounds. :)
You are right, "Let the tests guide you" is not easy! You may at first
treat it like a game with simple rules: don't write more code than is
needed to pass hte test. Focus on the process, not on your deadline. It may
be easier to do that on a kata rather than on real work :)
http://online-training.jbrains.ca/p/wbitdd-01
Matteo
Post by Dariusz Gafka
W dniu środa, 26 października 2016 23:29:10 UTC+2 uÅŒytkownik Israel
Post by Israel Fonseca
Round 2 :)
1.a Maybe I didn't get it right, but if you use a real instance it
won't solve the problem of having to change all the tests in the case that
you figure out that you don't need the factory anymore. When you say: "my
tests will depend on existence of it" as a bad thing, I don't agree. You
are testing a class that depends on another collaborators and makes sense
to the test express this necessity somehow (you have to give a
real/fake/stub/mock implementation to it). By having to handle this
dependency in your test, the test is also giving some feedback about your
design (when you happen to have 5+ collaborators you will think "man,
there's something wrong in here").
2. In that case, yes, I would create a test to check if my TransactionService
handles the failure accordingly (write some log file), and for that I would
stub the collaborator to throw an exception and check the logging (and yes,
It'll be like a repeated test, but one case if for identifying an error and
the other is about how to handle the error).
https://vimeo.com/80533536
Em qua, 26 de out de 2016 às 17:40, Matteo Vaccari <
Post by Matteo Vaccari
Hi Dariusz,
this example code does not seem to do much, now, does it? Perhaps
the only interesting thing that happens here is in the getFor() method,
which you didn't show. This looks to me like you came up with a solution,
and you're now trying to write tests that prove that your solution exists.
Good tests (IMO) are tests that talk about specific cases of business
things that are interesting to your customer.
forget about the TransactionProvider and the TransactionProviderFactory
altogether. Write a test that
How about you start with a test of what interesting things happen,
from the point of view of the business, when someone calls
transfer(new Money(1), "whatever")
Try to solve it in the simplest possible way, then proceed with the
next variation of
transfer(X, Y)
that makes sense to the business. Don't write more code than is
required to pass the tests. Let the tests guide you.
Hope this helps,
Matteo
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So
here we go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory =
transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API,
that is exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do
something else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not
existing TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it,
send an email to
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dariusz Gafka
2016-10-28 07:33:30 UTC
Permalink
Seems, that the thing I was looking for is "Detroid school of TDD".

"Every test written in a Detroit-school test suite is designed to maximize
regression safety. As a result, testing the subject
<https://github.com/testdouble/contributing-tests/wiki/Subject> under
sufficiently realistic conditions is considered paramount to maximize the
resulting tests' regression value. Therefore, use of test doubles
<https://github.com/testdouble/contributing-tests/wiki/Test-Double> is seen
as an affordance to be minimized, often by reworking the broader design to
obviate them.

This introduces a surprisingly complex responsibility of Detroit-school TDD
practitioners: to define what level of realism is acceptable for a test to
be called a "unit test". Rules similar to the ones published by Michael
Feathers in 2005 <http://www.artima.com/weblogs/viewpost.jsp?thread=126923> are
common and often debated within teams as suites grow and become slower.

By using test doubles
<https://github.com/testdouble/contributing-tests/wiki/Test-Double> as a
convenience to work around slow dependencies or too-difficult-to-test
situations (e.g. verifying a side-effect occurred), the unit tests in a
Detroit-school suite tend to be heavily incidentally dependent on the
behavior of the subject
<https://github.com/testdouble/contributing-tests/wiki/Subject>'s
dependencies. This acts as a double-edged sword: on one hand, when the
behavior of a dependency changes in an unanticipated way, tests of its
users will helpfully fail; on the other hand, large test suites will
exhibit the problems caused by highly redundant coverage
<https://github.com/testdouble/contributing-tests/wiki/Redundant-Coverage>.

In contrast, London-school
<https://github.com/testdouble/contributing-tests/wiki/London-school-TDD> practitioners
tend to have very clearly defined rules for when to use mocks. Because very
few people in the broader public understand that there are two camps—much
less the nuanced differences between them—a developer brought up in the
Detroit-school will often look at a London-school unit test suite and
immediately draw the conclusion that it has succumbed to extreme
over-mocking
<https://github.com/testdouble/contributing-tests/wiki/over-mocking>."


"A common pattern to emerge when practicing Detroit-school TDD is that an
author will write some number of examples against a single public API,
which in turn necessitates the creation of numerous private methods, which
then leads to relatively large and unwieldy units. This places all the
design pressure on the author to answer for themselves questions like:

- "I have a large unit, what proper Design Patterns™ can I refactor this
into?" (Blank-slate syndrome
<http://blog.codinghorror.com/avoiding-blank-page-syndrome/>)
- "How many examples are enough to test the unit at this level of
granularity?"
- "At what point are my implementation's private methods sufficiently
complex that they warrant the creation of a separately-tested public API?"
- "What degree of redundant test coverage
<https://github.com/testdouble/contributing-tests/wiki/Redundant-Coverage> between
the original public API and any subsequently-extracted public APIs is
acceptable? Once that threshold is crossed, should redundant examples be
culled or should the newly-extracted API be replaced by a test double
<https://github.com/testdouble/contributing-tests/wiki/Test-Double> in
the original test?"

Above comes
from https://github.com/testdouble/contributing-tests/wiki/Detroit-school-TDD

W dniu środa, 26 października 2016 20:03:28 UTC+2 uÅŒytkownik Dariusz Gafka
Post by Dariusz Gafka
Hello,
I am strugling with one problem about testing public interface only.
I think the best explanation will be, if I start with example. So here we
go :)
We are having
public class TransactionService {
private TransactionProviderFactory transactionProviderFactory;
TransactionService(TransactionProviderFactory
transactionProviderFactory) {
this.transactionProviderFactory = transactionProviderFactory;
}
public void transfer(Money money, String type)
{
transactionProvider =
this.transactionProviderFactory.getFor(type);
transactionProvider.startTransaction(money);
}
}
class TransactionProviderFactory {
TransactionProvider getFor(String type) {
//returns for type
}
}
Now let's say they both belongs to the same package.
1. I should test only TransactionService as it's the only API, that is
exposed in this package. Other packages should only talk to
TransactionService, not other class in this package.
But now constructing TransactionService for tests requires
TransactionProviderFactory, which I shouldn't know about, because it's
internal to the package.
How should I handle it?
Should I mock it or create real instance and inject or maybe do something
else with it?
2. The TransactionProviderFactory contains logic also.
It should be tested against returning correct Provider for specific type.
It should be tested for throwing exception when retrieving not existing
TransactionProvider.
Should I write the above tests for TransactionService?
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Nat Pryce
2016-10-28 12:17:04 UTC
Permalink
when the behavior of a dependency changes in an unanticipated way, tests
of its users will helpfully fail...
I don't find the distinction between London/Detroit or Mockist/Classical
useful. I've written about that before on this list. But this sentence
highlights why:

Mocks are a tool for testing objects that tell other objects either (a)
"Make something happen!", or (b) "Something has happened, and you might
need to react in some way!". The object should not care what behaviour
results or even have visibility of it. If it does, a mock library is the
wrong tool. In that case, I'd either use the same implementation of the
dependency that is used in the deployed system, or write an in-memory
implementation of the protocol between object and dependency, and use
contract tests to ensure that it behaves the same as the implementation
used in the deployed system.

--Nat
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Israel Fonseca
2016-10-28 15:05:29 UTC
Permalink
Nat, so are you in favor of using an InMemory implementation of an
Repository if the objective is to control the indirect inputs of the SUT?
Because if you stub a query method with a Mock Framework and that real
implementation changes later, you won't get the "when the behavior of a
dependency changes in an unanticipated way tests of its users will
helpfully fail [...]" benefit.
when the behavior of a dependency changes in an unanticipated way, tests
of its users will helpfully fail...
I don't find the distinction between London/Detroit or Mockist/Classical
useful. I've written about that before on this list. But this sentence
Mocks are a tool for testing objects that tell other objects either (a)
"Make something happen!", or (b) "Something has happened, and you might
need to react in some way!". The object should not care what behaviour
results or even have visibility of it. If it does, a mock library is the
wrong tool. In that case, I'd either use the same implementation of the
dependency that is used in the deployed system, or write an in-memory
implementation of the protocol between object and dependency, and use
contract tests to ensure that it behaves the same as the implementation
used in the deployed system.
--Nat
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Nat Pryce
2016-10-28 16:47:12 UTC
Permalink
Post by Israel Fonseca
Nat, so are you in favor of using an InMemory implementation of an
Repository if the objective is to control the indirect inputs of the SUT?
Because if you stub a query method with a Mock Framework and that real
implementation changes later, you won't get the "when the behavior of a
dependency changes in an unanticipated way tests of its users will
helpfully fail [...]" benefit.
Yes. If it's simple lookups, then it's easy to implement with a map. If
it's a more complicated interface with a mix of queries and commands that
have interrelated behaviour, then a contract test is even more important.

--Nat
Post by Israel Fonseca
when the behavior of a dependency changes in an unanticipated way, tests
of its users will helpfully fail...
I don't find the distinction between London/Detroit or Mockist/Classical
useful. I've written about that before on this list. But this sentence
Mocks are a tool for testing objects that tell other objects either (a)
"Make something happen!", or (b) "Something has happened, and you might
need to react in some way!". The object should not care what behaviour
results or even have visibility of it. If it does, a mock library is the
wrong tool. In that case, I'd either use the same implementation of the
dependency that is used in the deployed system, or write an in-memory
implementation of the protocol between object and dependency, and use
contract tests to ensure that it behaves the same as the implementation
used in the deployed system.
--Nat
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Israel Fonseca
2016-10-28 19:19:38 UTC
Permalink
Interesting, you use this a golden rule and always create contract tests
for your in-memory implementations or just for those complicated
interfaces? I feel a little bad (or just lazy) with the idea of creating
contract test for all my InMemory implementations.

An finally, so you would mix InMemoryImplementations and mocks in your unit
tests. For example to test the following code (very dumb example):

class CheckUserPermissionUsecase{

constructor(userGateway, output)
this.userGateway = userGateway
this.output = output

execute(name){
user = this.userGateway.find(name)
if(user.age > 18)
this.output.display('Allow')
else{
user.incrementNumberOfFailedAttempts()
this.userGateway.update(user)
this.output.display('Do not allow')
}
}
}

You would mock the output and assert that the display method sent the right
message, and for the increment in the user you would query the
InMemoryDatabase and check for the changed value. That's right?

I missed this kind of examples in the GOOS book, so it's interesting to
know your opinion. :)
Post by Israel Fonseca
Nat, so are you in favor of using an InMemory implementation of an
Repository if the objective is to control the indirect inputs of the SUT?
Because if you stub a query method with a Mock Framework and that real
implementation changes later, you won't get the "when the behavior of a
dependency changes in an unanticipated way tests of its users will
helpfully fail [...]" benefit.
Yes. If it's simple lookups, then it's easy to implement with a map. If
it's a more complicated interface with a mix of queries and commands that
have interrelated behaviour, then a contract test is even more important.
--Nat
when the behavior of a dependency changes in an unanticipated way, tests
of its users will helpfully fail...
I don't find the distinction between London/Detroit or Mockist/Classical
useful. I've written about that before on this list. But this sentence
Mocks are a tool for testing objects that tell other objects either (a)
"Make something happen!", or (b) "Something has happened, and you might
need to react in some way!". The object should not care what behaviour
results or even have visibility of it. If it does, a mock library is the
wrong tool. In that case, I'd either use the same implementation of the
dependency that is used in the deployed system, or write an in-memory
implementation of the protocol between object and dependency, and use
contract tests to ensure that it behaves the same as the implementation
used in the deployed system.
--Nat
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dariusz Gafka
2016-10-29 07:05:45 UTC
Permalink
Nat,
If the Israel's example is true, I understand you mock every object that
doesn't return values, and you create in memory implementation or use real
ones for query objects.
If that's true, do you write acceptance tests?
And where do you set state for UserGateway, in some setup for your test
case?


This is something really interesting. Using in memory in unit tests truly
decouples the test cases from implementation.
And why not to go any forward and create dumb implementations instead of
using mocks? :) (write methods)

W dniu piątek, 28 października 2016 21:19:52 UTC+2 uÅŒytkownik Israel
Post by Israel Fonseca
Interesting, you use this a golden rule and always create contract tests
for your in-memory implementations or just for those complicated
interfaces? I feel a little bad (or just lazy) with the idea of creating
contract test for all my InMemory implementations.
An finally, so you would mix InMemoryImplementations and mocks in your
class CheckUserPermissionUsecase{
constructor(userGateway, output)
this.userGateway = userGateway
this.output = output
execute(name){
user = this.userGateway.find(name)
if(user.age > 18)
this.output.display('Allow')
else{
user.incrementNumberOfFailedAttempts()
this.userGateway.update(user)
this.output.display('Do not allow')
}
}
}
You would mock the output and assert that the display method sent the
right message, and for the increment in the user you would query the
InMemoryDatabase and check for the changed value. That's right?
I missed this kind of examples in the GOOS book, so it's interesting to
know your opinion. :)
Post by Nat Pryce
Post by Israel Fonseca
Nat, so are you in favor of using an InMemory implementation of an
Repository if the objective is to control the indirect inputs of the SUT?
Because if you stub a query method with a Mock Framework and that real
implementation changes later, you won't get the "when the behavior of a
dependency changes in an unanticipated way tests of its users will
helpfully fail [...]" benefit.
Yes. If it's simple lookups, then it's easy to implement with a map. If
it's a more complicated interface with a mix of queries and commands that
have interrelated behaviour, then a contract test is even more important.
--Nat
Post by Israel Fonseca
Post by Nat Pryce
when the behavior of a dependency changes in an unanticipated way,
tests of its users will helpfully fail...
I don't find the distinction between London/Detroit or
Mockist/Classical useful. I've written about that before on this list. But
Mocks are a tool for testing objects that tell other objects either (a)
"Make something happen!", or (b) "Something has happened, and you might
need to react in some way!". The object should not care what behaviour
results or even have visibility of it. If it does, a mock library is the
wrong tool. In that case, I'd either use the same implementation of the
dependency that is used in the deployed system, or write an in-memory
implementation of the protocol between object and dependency, and use
contract tests to ensure that it behaves the same as the implementation
used in the deployed system.
--Nat
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Nat Pryce
2016-10-31 10:18:45 UTC
Permalink
In that example, the CheckUserPermissionsUsecase class seems to have mixed
responsibilities. It has to do three things -- find a user, check age
restriction, report whether a user is allowed or not. But it reports that
the user is not allowed to two different objects -- the display and the
user -- and must persist users correctly in the user gateway, otherwise (I
guess) the app won't work. That makes me think that it has too much
knowledge of how the rest of the application is structured. The interfaces
it depends on are not defined in *its* terms, but in terms of the rest of
the application's implementation details. I'd want to push that knowledge
out, so that its implementation is only concerned with its main
responsibility, which appears to be enforcing age restrictions. So I'd give
it a way to look up users, and a way to report the result of its check as
an event. Something like:

interface UserLookup {
fun findByName(name: String): User
}

interface PermissionDecision {
fun rejected(user: User)
fun allowed(user: User)
}

and then the check could be implemented as:

class UserAgeRestriction(val users: UserLookup, val decision:
PermissionDecision) {
fun execute(name: String) {
val user = users.findByName(name)
if (user.age > 18) {
decision.rejected(user)
} else {
decision.allowed(user)
}
}

An implementation of PermissionDecision would display the decision to the
display and increment a counter for the user, and whatever policies are
needed by the rest of the application.

Now, looking up the user and reporting the events are very simple and could
well be tested with a mock object library. But the user lookup could be
just as easily be implemented with a map in unit tests.

--Nat
Post by Dariusz Gafka
Nat,
If the Israel's example is true, I understand you mock every object that
doesn't return values, and you create in memory implementation or use real
ones for query objects.
If that's true, do you write acceptance tests?
And where do you set state for UserGateway, in some setup for your test
case?
This is something really interesting. Using in memory in unit tests truly
decouples the test cases from implementation.
And why not to go any forward and create dumb implementations instead of
using mocks? :) (write methods)
W dniu piątek, 28 października 2016 21:19:52 UTC+2 uÅŒytkownik Israel
Post by Israel Fonseca
Interesting, you use this a golden rule and always create contract tests
for your in-memory implementations or just for those complicated
interfaces? I feel a little bad (or just lazy) with the idea of creating
contract test for all my InMemory implementations.
An finally, so you would mix InMemoryImplementations and mocks in your
class CheckUserPermissionUsecase{
constructor(userGateway, output)
this.userGateway = userGateway
this.output = output
execute(name){
user = this.userGateway.find(name)
if(user.age > 18)
this.output.display('Allow')
else{
user.incrementNumberOfFailedAttempts()
this.userGateway.update(user)
this.output.display('Do not allow')
}
}
}
You would mock the output and assert that the display method sent the
right message, and for the increment in the user you would query the
InMemoryDatabase and check for the changed value. That's right?
I missed this kind of examples in the GOOS book, so it's interesting to
know your opinion. :)
Post by Nat Pryce
Post by Israel Fonseca
Nat, so are you in favor of using an InMemory implementation of an
Repository if the objective is to control the indirect inputs of the SUT?
Because if you stub a query method with a Mock Framework and that real
implementation changes later, you won't get the "when the behavior of
a dependency changes in an unanticipated way tests of its users will
helpfully fail [...]" benefit.
Yes. If it's simple lookups, then it's easy to implement with a map.
If it's a more complicated interface with a mix of queries and commands
that have interrelated behaviour, then a contract test is even more
important.
--Nat
Post by Israel Fonseca
Post by Nat Pryce
when the behavior of a dependency changes in an unanticipated way,
tests of its users will helpfully fail...
I don't find the distinction between London/Detroit or
Mockist/Classical useful. I've written about that before on this list. But
Mocks are a tool for testing objects that tell other objects either
(a) "Make something happen!", or (b) "Something has happened, and you might
need to react in some way!". The object should not care what behaviour
results or even have visibility of it. If it does, a mock library is the
wrong tool. In that case, I'd either use the same implementation of the
dependency that is used in the deployed system, or write an in-memory
implementation of the protocol between object and dependency, and use
contract tests to ensure that it behaves the same as the implementation
used in the deployed system.
--Nat
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
com.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
com.
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
com.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Nat Pryce
2016-10-31 09:52:50 UTC
Permalink
Post by Israel Fonseca
Interesting, you use this a golden rule and always create contract tests
for your in-memory implementations or just for those complicated
interfaces? I feel a little bad (or just lazy) with the idea of creating
contract test for all my InMemory implementations.
As a rule of thumb, I'll end up with contract tests by refactoring. I
don't write them *for* in-memory implementations. I'll write a test, and
then pull out the commonalities into a contract test that can be applied to
different implementations, the in-memory implementation being one of them.
Post by Israel Fonseca
An finally, so you would mix InMemoryImplementations and mocks in your
unit tests.
Sometimes. I do find a mock library useful for testing event emission and
outgoing commands in a tell-don't-ask style.
Post by Israel Fonseca
class CheckUserPermissionUsecase{
constructor(userGateway, output)
this.userGateway = userGateway
this.output = output
execute(name){
user = this.userGateway.find(name)
if(user.age > 18)
this.output.display('Allow')
else{
user.incrementNumberOfFailedAttempts()
this.userGateway.update(user)
this.output.display('Do not allow')
}
}
}
You would mock the output and assert that the display method sent the
right message, and for the increment in the user you would query the
InMemoryDatabase and check for the changed value. That's right?
I missed this kind of examples in the GOOS book, so it's interesting to
know your opinion. :)
Post by Israel Fonseca
Nat, so are you in favor of using an InMemory implementation of an
Repository if the objective is to control the indirect inputs of the SUT?
Because if you stub a query method with a Mock Framework and that real
implementation changes later, you won't get the "when the behavior of a
dependency changes in an unanticipated way tests of its users will
helpfully fail [...]" benefit.
Yes. If it's simple lookups, then it's easy to implement with a map. If
it's a more complicated interface with a mix of queries and commands that
have interrelated behaviour, then a contract test is even more important.
--Nat
when the behavior of a dependency changes in an unanticipated way, tests
of its users will helpfully fail...
I don't find the distinction between London/Detroit or Mockist/Classical
useful. I've written about that before on this list. But this sentence
Mocks are a tool for testing objects that tell other objects either (a)
"Make something happen!", or (b) "Something has happened, and you might
need to react in some way!". The object should not care what behaviour
results or even have visibility of it. If it does, a mock library is the
wrong tool. In that case, I'd either use the same implementation of the
dependency that is used in the deployed system, or write an in-memory
implementation of the protocol between object and dependency, and use
contract tests to ensure that it behaves the same as the implementation
used in the deployed system.
--Nat
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Grzegorz Gałęzowski
2016-10-29 09:22:03 UTC
Permalink
Nat,

If that is the case, then what about the jmock's syntax such as allowing
(turtle).queryPen(); will(returnValue(PEN_DOWN));? Do you not find it
useful anymore? And what about the "allow queries, expect commands" advice?

Regards,
grzesiek
Post by Nat Pryce
Post by Israel Fonseca
Nat, so are you in favor of using an InMemory implementation of an
Repository if the objective is to control the indirect inputs of the SUT?
Because if you stub a query method with a Mock Framework and that real
implementation changes later, you won't get the "when the behavior of a
dependency changes in an unanticipated way tests of its users will
helpfully fail [...]" benefit.
Yes. If it's simple lookups, then it's easy to implement with a map. If
it's a more complicated interface with a mix of queries and commands that
have interrelated behaviour, then a contract test is even more important.
--Nat
Post by Israel Fonseca
Post by Nat Pryce
when the behavior of a dependency changes in an unanticipated way,
tests of its users will helpfully fail...
I don't find the distinction between London/Detroit or Mockist/Classical
useful. I've written about that before on this list. But this sentence
Mocks are a tool for testing objects that tell other objects either (a)
"Make something happen!", or (b) "Something has happened, and you might
need to react in some way!". The object should not care what behaviour
results or even have visibility of it. If it does, a mock library is the
wrong tool. In that case, I'd either use the same implementation of the
dependency that is used in the deployed system, or write an in-memory
implementation of the protocol between object and dependency, and use
contract tests to ensure that it behaves the same as the implementation
used in the deployed system.
--Nat
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
an email to
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
<javascript:>.
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Nat Pryce
2016-10-31 10:27:39 UTC
Permalink
On 29 October 2016 at 10:22, Grzegorz Gałęzowski <
Post by Grzegorz Gałęzowski
Nat,
If that is the case, then what about the jmock's syntax such as allowing
(turtle).queryPen(); will(returnValue(PEN_DOWN));? Do you not find it
useful anymore? And what about the "allow queries, expect commands" advice?
Partly experience -- we've learned how to use the tools more effectively
over the years. Partly language -- I'm now writing almost exclusively in
Kotlin, not Java, and it's much easier to write one-off implementations of
an interface for testing in Kotlin than in Java.

In Java I would probably use the `allowing` syntax with very
straightforward query interfaces, like factories and the like, because it
is still much less verbose than writing an object. But as soon as the
object's interface became more complicated I'd switch to an in-memory
implementation.

I still follow the rule of thumb of "allow queries, expect commands", for
the same reasons, whether using a mock object library or not.

Cheers,
--Nat
Post by Grzegorz Gałęzowski
Regards,
grzesiek
Post by Nat Pryce
Post by Israel Fonseca
Nat, so are you in favor of using an InMemory implementation of an
Repository if the objective is to control the indirect inputs of the SUT?
Because if you stub a query method with a Mock Framework and that real
implementation changes later, you won't get the "when the behavior of a
dependency changes in an unanticipated way tests of its users will
helpfully fail [...]" benefit.
Yes. If it's simple lookups, then it's easy to implement with a map. If
it's a more complicated interface with a mix of queries and commands that
have interrelated behaviour, then a contract test is even more important.
--Nat
Post by Israel Fonseca
Post by Nat Pryce
when the behavior of a dependency changes in an unanticipated way,
tests of its users will helpfully fail...
I don't find the distinction between London/Detroit or
Mockist/Classical useful. I've written about that before on this list. But
Mocks are a tool for testing objects that tell other objects either (a)
"Make something happen!", or (b) "Something has happened, and you might
need to react in some way!". The object should not care what behaviour
results or even have visibility of it. If it does, a mock library is the
wrong tool. In that case, I'd either use the same implementation of the
dependency that is used in the deployed system, or write an in-memory
implementation of the protocol between object and dependency, and use
contract tests to ensure that it behaves the same as the implementation
used in the deployed system.
--Nat
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
com.
For more options, visit https://groups.google.com/d/optout.
--
---
You received this message because you are subscribed to the Google
Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send
com.
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups
"Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an
For more options, visit https://groups.google.com/d/optout.
--
http://www.natpryce.com
--
---
You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriented-software+***@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Loading...