This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Testing methods-within-methods

15 replies
Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
A post recently about private methods being a "code smell" (i.e. they should be replaced by methods-within-methods) got me thinking about how we could effectively test such code. 
I find it is usually *exactly* this sort of thing we want to test; for example a public method needs to perform some specific slicing'n'dicing of some collections which we wish to refactor into a sub-computation and test that we have got that sub-computation right.
I wonder, are there any plans along these lines (perhaps as part of the scala reflection API)?
Chris
Ben Hutchison 3
Joined: 2009-11-02,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods

Local Functions (I think they're called?) are /closures/, in that they
can refer to their enclosing scope(s).

So... to test one in isolation, would require in the general case, a
facility to specify the parameters that have been passed to each
enclosing scope.

Pragmatically, I'd say that want you wish to test Local Functions in
isolation, make them regular private methods that take all params
explicitly.

-Ben.

On Tue, Aug 17, 2010 at 3:14 AM, christopher marshall
wrote:
> A post recently about private methods being a "code smell" (i.e. they should
> be replaced by methods-within-methods) got me thinking about how we could
> effectively test such code.
> I find it is usually *exactly* this sort of thing we want to test; for
> example a public method needs to perform some specific slicing'n'dicing of
> some collections which we wish to refactor into a sub-computation and test
> that we have got that sub-computation right.
> I wonder, are there any plans along these lines (perhaps as part of the
> scala reflection API)?
> Chris

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: Testing methods-within-methods

On Monday August 16 2010, christopher marshall wrote:
> A post recently about private methods being a "code smell" (i.e. they
> should be replaced by methods-within-methods) got me thinking about
> how we could effectively test such code.

An alternate formulation of a class that has the same public behavior is
indistinguishable. There's no reason to favor one over the other, at
least not based solely on some imagined odor emanating from one but not
the other.

> I find it is usually
> *exactly* this sort of thing we want to test; for example a public
> method needs to perform some specific slicing'n'dicing of some
> collections which we wish to refactor into a sub-computation and test
> that we have got that sub-computation right. I wonder, are there any
> plans along these lines (perhaps as part of the scala reflection
> API)? Chris

By their nature, nested methods are not part of a public API. In fact,
they have no independent existence. I see no reason to test them
independently. The finest meaningful granularity of testing is the
externally accessible members (including those accessible to companions
and subclasses) of the class or trait.

Randall Schulz

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods
Could you remind me what the argument against top level private methods was?

On Mon, Aug 16, 2010 at 1:14 PM, christopher marshall <oxbow_lakes [at] hotmail [dot] com> wrote:
A post recently about private methods being a "code smell" (i.e. they should be replaced by methods-within-methods) got me thinking about how we could effectively test such code. 
I find it is usually *exactly* this sort of thing we want to test; for example a public method needs to perform some specific slicing'n'dicing of some collections which we wish to refactor into a sub-computation and test that we have got that sub-computation right.
I wonder, are there any plans along these lines (perhaps as part of the scala reflection API)?
Chris

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Testing methods-within-methods
Code smell of functionality that would be better placed in another class.

On Tue, Aug 17, 2010 at 4:24 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Could you remind me what the argument against top level private methods was?

On Mon, Aug 16, 2010 at 1:14 PM, christopher marshall <oxbow_lakes [at] hotmail [dot] com> wrote:
A post recently about private methods being a "code smell" (i.e. they should be replaced by methods-within-methods) got me thinking about how we could effectively test such code. 
I find it is usually *exactly* this sort of thing we want to test; for example a public method needs to perform some specific slicing'n'dicing of some collections which we wish to refactor into a sub-computation and test that we have got that sub-computation right.
I wonder, are there any plans along these lines (perhaps as part of the scala reflection API)?
Chris




--
Daniel C. Sobral

I travel to the future all the time.
Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods
I think it's a too-broad generalization.Or maybe the conclusion that code with such a label is always wrong, is too broad.

Anyway, what about this example? Not actual code; more like how some actual code should be. Take a singleton object called LCS. LCS stands for least common subsequence (or something like that). One use is to calculate a diff (as in the unix command) of two sequences; once you have an LCS of two sequences you can calculate their diff by comparing the LCS both actual sequences. But it's also useful for other reasons. Anyway, the basic LCS algorithm could be understood in terms of recursion, but it's much more efficient to use a dynamic programming technique which consists of building a matrix of hints. Now if you want the actual LCS, you run the LCS algorithm. But if you want the diff, you don't have to actually calculate the LCS; once you build this special backtracking matrix you can generate the diff straight from the matrix. But the matrix is not really generally useful and should not a public API. So wouldn't it make sense to have two public methods, one to return the LCS and one to return the diff (plus anything else that works off this special matrix), and let them share a private method that builds the matrix?



On Tue, Aug 17, 2010 at 5:19 PM, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
Code smell of functionality that would be better placed in another class.

On Tue, Aug 17, 2010 at 4:24 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Could you remind me what the argument against top level private methods was?

On Mon, Aug 16, 2010 at 1:14 PM, christopher marshall <oxbow_lakes [at] hotmail [dot] com> wrote:
A post recently about private methods being a "code smell" (i.e. they should be replaced by methods-within-methods) got me thinking about how we could effectively test such code. 
I find it is usually *exactly* this sort of thing we want to test; for example a public method needs to perform some specific slicing'n'dicing of some collections which we wish to refactor into a sub-computation and test that we have got that sub-computation right.
I wonder, are there any plans along these lines (perhaps as part of the scala reflection API)?
Chris




--
Daniel C. Sobral

I travel to the future all the time.

Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: Testing methods-within-methods
Does it not make even more sense to push the matrix logic into a separate class, with its own unit tests.  Then to hold an instance of this class in the LCS singleton?
They could even be defined in the same source file.

On 18 August 2010 00:04, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
I think it's a too-broad generalization.Or maybe the conclusion that code with such a label is always wrong, is too broad.

Anyway, what about this example? Not actual code; more like how some actual code should be. Take a singleton object called LCS. LCS stands for least common subsequence (or something like that). One use is to calculate a diff (as in the unix command) of two sequences; once you have an LCS of two sequences you can calculate their diff by comparing the LCS both actual sequences. But it's also useful for other reasons. Anyway, the basic LCS algorithm could be understood in terms of recursion, but it's much more efficient to use a dynamic programming technique which consists of building a matrix of hints. Now if you want the actual LCS, you run the LCS algorithm. But if you want the diff, you don't have to actually calculate the LCS; once you build this special backtracking matrix you can generate the diff straight from the matrix. But the matrix is not really generally useful and should not a public API. So wouldn't it make sense to have two public methods, one to return the LCS and one to return the diff (plus anything else that works off this special matrix), and let them share a private method that builds the matrix?



On Tue, Aug 17, 2010 at 5:19 PM, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
Code smell of functionality that would be better placed in another class.

On Tue, Aug 17, 2010 at 4:24 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Could you remind me what the argument against top level private methods was?

On Mon, Aug 16, 2010 at 1:14 PM, christopher marshall <oxbow_lakes [at] hotmail [dot] com> wrote:
A post recently about private methods being a "code smell" (i.e. they should be replaced by methods-within-methods) got me thinking about how we could effectively test such code. 
I find it is usually *exactly* this sort of thing we want to test; for example a public method needs to perform some specific slicing'n'dicing of some collections which we wish to refactor into a sub-computation and test that we have got that sub-computation right.
I wonder, are there any plans along these lines (perhaps as part of the scala reflection API)?
Chris




--
Daniel C. Sobral

I travel to the future all the time.




--
Kevin Wright

mail/google talk: kev [dot] lee [dot] wright [at] gmail [dot] com
wave: kev [dot] lee [dot] wright [at] googlewave [dot] com
skype: kev.lee.wright
twitter: @thecoda

Chris Marshall
Joined: 2009-06-17,
User offline. Last seen 44 weeks 3 days ago.
RE: Testing methods-within-methods
It makes sense for functionality to be scoped as restrictively as possible; obviously we want to refactor either shared or distinct functionality into separate-units be they methods or functions. Taking these together, almost *all* of what I would have refactored into a private method in Java ends up as a method-within-method (because it is not required from more than one "public" method.
Chris
PS. And I miss being able to test it

Date: Tue, 17 Aug 2010 15:24:07 -0400
Subject: Re: [scala-debate] Testing methods-within-methods
From: naftoligug [at] gmail [dot] com

Could you remind me what the argument against top level private methods was?
Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods
On Tue, Aug 17, 2010 at 8:45 PM, Kevin Wright <kev [dot] lee [dot] wright [at] gmail [dot] com> wrote:
Does it not make even more sense to push the matrix logic into a separate class, with its own unit tests.  Then to hold an instance of this class in the LCS singleton?


You're asking me if it makes more sense? That's what I'm asking you! :)
Seriously though, what purpose would it fulfill? Why would I want to have a special unit test for the backtracking matrix, which is not useful on its own?Either the unit test for the diff passes or it fails. It's true that if it fails having a unit test on the backtracking matrix would help narrow down the bug, but by that logic every line of code should be its own public and unit tested method. The point is, that since it only exist for internal purposes, there is no intrinsic value in knowing whether it works or not (by intrinsic I mean to say that knowing whether it works or not is only valuable to the extent it pertains to the public methods). Moreover, there are more efficient LCS algorithms (or implementations of the algorithm) and hopefully one will eventually replace the backtracking matrix. Again, this underscores the fact that the backtracking matrix is simply an implementation detail. An implementation detail that is used in more than one place. Is that so rare?


They could even be defined in the same source file.

On 18 August 2010 00:04, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
I think it's a too-broad generalization.Or maybe the conclusion that code with such a label is always wrong, is too broad.

Anyway, what about this example? Not actual code; more like how some actual code should be. Take a singleton object called LCS. LCS stands for least common subsequence (or something like that). One use is to calculate a diff (as in the unix command) of two sequences; once you have an LCS of two sequences you can calculate their diff by comparing the LCS both actual sequences. But it's also useful for other reasons. Anyway, the basic LCS algorithm could be understood in terms of recursion, but it's much more efficient to use a dynamic programming technique which consists of building a matrix of hints. Now if you want the actual LCS, you run the LCS algorithm. But if you want the diff, you don't have to actually calculate the LCS; once you build this special backtracking matrix you can generate the diff straight from the matrix. But the matrix is not really generally useful and should not a public API. So wouldn't it make sense to have two public methods, one to return the LCS and one to return the diff (plus anything else that works off this special matrix), and let them share a private method that builds the matrix?



On Tue, Aug 17, 2010 at 5:19 PM, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
Code smell of functionality that would be better placed in another class.

On Tue, Aug 17, 2010 at 4:24 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Could you remind me what the argument against top level private methods was?

On Mon, Aug 16, 2010 at 1:14 PM, christopher marshall <oxbow_lakes [at] hotmail [dot] com> wrote:
A post recently about private methods being a "code smell" (i.e. they should be replaced by methods-within-methods) got me thinking about how we could effectively test such code. 
I find it is usually *exactly* this sort of thing we want to test; for example a public method needs to perform some specific slicing'n'dicing of some collections which we wish to refactor into a sub-computation and test that we have got that sub-computation right.
I wonder, are there any plans along these lines (perhaps as part of the scala reflection API)?
Chris




--
Daniel C. Sobral

I travel to the future all the time.




--
Kevin Wright

mail/google talk: kev [dot] lee [dot] wright [at] gmail [dot] com
wave: kev [dot] lee [dot] wright [at] googlewave [dot] com
skype: kev.lee.wright
twitter: @thecoda


Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods
Almost *all* --- or *almost* all? :)

On Wed, Aug 18, 2010 at 10:35 AM, christopher marshall <oxbow_lakes [at] hotmail [dot] com> wrote:
It makes sense for functionality to be scoped as restrictively as possible; obviously we want to refactor either shared or distinct functionality into separate-units be they methods or functions. Taking these together, almost *all* of what I would have refactored into a private method in Java ends up as a method-within-method (because it is not required from more than one "public" method.
Chris
PS. And I miss being able to test it

Date: Tue, 17 Aug 2010 15:24:07 -0400
Subject: Re: [scala-debate] Testing methods-within-methods
From: naftoligug [at] gmail [dot] com

Could you remind me what the argument against top level private methods was?

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: Testing methods-within-methods

On Wednesday August 18 2010, christopher marshall wrote:
> ...
> PS. And I miss being able to test it

This boggles my mind.

Why do you care about testing something with no independent existence?
Do you actually write unit tests for private methods?

Randall Schulz

Justin du coeur
Joined: 2009-03-04,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods
I confess, I'm finding the question here kind of weird, especially on this list.
Consider: from a functional-programming POV, the *entire program* is essentially an isolated black box, and its contents considered private to it.  It would be conceptually reasonable to treat all of its internal algorithms as "internal".  So by this logic, why would we want to test *anything* inside of it?
Okay, this is a bit of a reductio ad absurdam, but I do think it gets to the point, that privacy is only tangentially to what we want to test.  The privacy of a sub-algorithm usually pertains to whether we think it is so peculiar to this situation that exposing it publicly just complicates things.  But whether we want to unit-test it or not has nothing to do with that: it has to do with the complexity of that particular chunk of code.  
Granted, these tend to be related in practice, but there's nothing automatic about that.  In principle, it seems quite reasonable to me that you might have a functional block that is extremely specific to a particular problem (and hence, you might want it to be private), but is still pretty complex (and hence, you may want to be able to independently unit-test it).
Or to look at it another way, "no independent existence" is never true for code that is actually executed.  Even an enclosed function still has one dependent: the function that is wrapping it.  And it is quite reasonable that you might want to test the sub-function, so that the external one knows it can be counted on...
On Wed, Aug 18, 2010 at 4:11 PM, Randall R Schulz <rschulz [at] sonic [dot] net> wrote:
On Wednesday August 18 2010, christopher marshall wrote:
> ...
> PS. And I miss being able to test it

This boggles my mind.

Why do you care about testing something with no independent existence?
Do you actually write unit tests for private methods?


Randall Schulz

Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods
Or to look at it another way, "no independent existence" is never true for code that is actually executed.  Even an enclosed function still has one dependent: the function that is wrapping it.  And it is quite reasonable that you might want to test the sub-function, so that the external one knows it can be counted on...

True, but one can differentiate between depended on *only* by a specific set of dependents which are all defined unit tested, and something that is needed to work because anyone should be able to depend on it.
Justin du coeur
Joined: 2009-03-04,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods
On Wed, Aug 18, 2010 at 10:07 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Or to look at it another way, "no independent existence" is never true for code that is actually executed.  Even an enclosed function still has one dependent: the function that is wrapping it.  And it is quite reasonable that you might want to test the sub-function, so that the external one knows it can be counted on...

True, but one can differentiate between depended on *only* by a specific set of dependents which are all defined unit tested, and something that is needed to work because anyone should be able to depend on it.
 Fair enough, but I don't think it invalidates the point: complex code is complex code.  It's true that a public API is *more* demanding of unit-testing, but it is entirely appropriate and common to want to unit test a completely private API if it is doing something complicated.  And once you get down to the inner-function level, there's currently no way to do so.  
(Nor is it obvious that it's even possible: while you can come up with ways to sneakily expose private methods for testing, it's arguably meaningless to "expose" a closure like that.  Interesting to speculate about how you *would* test something like that, though.  Could something be done with continuations?  Do purely functional languages provide any ways of wrestling with this?)
Mind, I don't think any of this is tragic.  My point is simply that there is sometimes a tension between the natural level of "publicness" for a function, and the desire to be able to unit-test it.  Some conceptually private functions really *should* be tested in isolation, when they are a component of a particularly complicated operation...
Naftoli Gugenheim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods
I hear that. But it's not possible to unit test a private method, right? So where are you going with this?

On Thu, Aug 19, 2010 at 9:09 AM, Justin du coeur <jducoeur [at] gmail [dot] com> wrote:
On Wed, Aug 18, 2010 at 10:07 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Or to look at it another way, "no independent existence" is never true for code that is actually executed.  Even an enclosed function still has one dependent: the function that is wrapping it.  And it is quite reasonable that you might want to test the sub-function, so that the external one knows it can be counted on...

True, but one can differentiate between depended on *only* by a specific set of dependents which are all defined unit tested, and something that is needed to work because anyone should be able to depend on it.
 Fair enough, but I don't think it invalidates the point: complex code is complex code.  It's true that a public API is *more* demanding of unit-testing, but it is entirely appropriate and common to want to unit test a completely private API if it is doing something complicated.  And once you get down to the inner-function level, there's currently no way to do so.  
(Nor is it obvious that it's even possible: while you can come up with ways to sneakily expose private methods for testing, it's arguably meaningless to "expose" a closure like that.  Interesting to speculate about how you *would* test something like that, though.  Could something be done with continuations?  Do purely functional languages provide any ways of wrestling with this?)
Mind, I don't think any of this is tragic.  My point is simply that there is sometimes a tension between the natural level of "publicness" for a function, and the desire to be able to unit-test it.  Some conceptually private functions really *should* be tested in isolation, when they are a component of a particularly complicated operation...

Justin du coeur
Joined: 2009-03-04,
User offline. Last seen 42 years 45 weeks ago.
Re: Testing methods-within-methods
Mostly I'm thinking out loud, frankly.  But it's worth noting that in principle you *could* unit-test a private method, with some compiler or reflection complicity -- from the conceptual viewpoint, private is largely an annotation, and doesn't change the method all that deeply.  You could build a harness that worked around it for unit-testing purposes, and it would make logical sense.  (It might be a hassle, and you can well argue that it's a bad idea, but it's Just Plain Work: there's nothing deeply strange about it.)
By contrast, an inner function is *seriously* private: it's not clear that even the compiler or reflection can expose it in any meaningful way, because of closure implications.  So in principle, it seems like unit-testing a method-within-a-method (getting back to the original topic) is almost meaningless.  At least, I'm not clear on how a general-case mechanism to do so would work; that, in turn, is leading me to wonder how the more strictly functional languages deal with this, or whether nobody actually tries to wrestle with this particular bit of weirdness...

On Thu, Aug 19, 2010 at 3:58 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
I hear that. But it's not possible to unit test a private method, right? So where are you going with this?

On Thu, Aug 19, 2010 at 9:09 AM, Justin du coeur <jducoeur [at] gmail [dot] com> wrote:
On Wed, Aug 18, 2010 at 10:07 PM, Naftoli Gugenheim <naftoligug [at] gmail [dot] com> wrote:
Or to look at it another way, "no independent existence" is never true for code that is actually executed.  Even an enclosed function still has one dependent: the function that is wrapping it.  And it is quite reasonable that you might want to test the sub-function, so that the external one knows it can be counted on...

True, but one can differentiate between depended on *only* by a specific set of dependents which are all defined unit tested, and something that is needed to work because anyone should be able to depend on it.
 Fair enough, but I don't think it invalidates the point: complex code is complex code.  It's true that a public API is *more* demanding of unit-testing, but it is entirely appropriate and common to want to unit test a completely private API if it is doing something complicated.  And once you get down to the inner-function level, there's currently no way to do so.  
(Nor is it obvious that it's even possible: while you can come up with ways to sneakily expose private methods for testing, it's arguably meaningless to "expose" a closure like that.  Interesting to speculate about how you *would* test something like that, though.  Could something be done with continuations?  Do purely functional languages provide any ways of wrestling with this?)
Mind, I don't think any of this is tragic.  My point is simply that there is sometimes a tension between the natural level of "publicness" for a function, and the desire to be able to unit-test it.  Some conceptually private functions really *should* be tested in isolation, when they are a component of a particularly complicated operation...


Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland