Agreed. Or you could just implement the reflection
yourself, it isn't that hard. That does not address the
brittleness in your tests, though.
One other interesting approach I've seen with TDD is to
make all the "significant" methods
public so they can be exposed to the test classes, but
then define separate interfaces to be the contract
external callers use. This way you get easier
testability by not having to go through a
wrapper/reflection while at the same time still
retaining some control on which methods external objects
can call. In terms of "significant"
methods -- they would be those that had enough
complexity behind them that you feel they warrant their
own test case. It also requires thinking about the
interface separate from the class itself which might be
considered an added benefit.
Hello everyone, I'm the dev for this feature, and I just
wanted to clarify a few points on this issue.
First of all, the generated tests will only use those
wrapper classes (officially, we call them
"private accessors") if the class
being tested is non-public, or if you selected a
non-public member to test. If your class is public, then
the "target" variable in the generated
test method will be an instance of the type being
tested. If it's not public, then we'll use the first
public type in its inheritance hierarchy. If the class
is public but the member we need to invoke is private,
then we'll still declare target as your type, and then
we'll create a separate variable to store an accessor
created from the target, and invoke the member on
*that*.
To sum up, if your type is public, there will always be
a variable of that type in the generated test, and if
you use Generate Method Stub on it, then the method will
be generated in the expected place. We expect people who
use private accessors in their hand-written tests to
follow the same pattern. Unfortunately, it's unlikely
that we'll be able to forward refactoring operations on
private accessors to the code under test, or vice versa
(so that if you Reorder Parameters on your
code-under-test, for example, your test code that uses a
private accessor will be fixed up as well). For now, we
attempt to mitigate the problem by using private
accessors only where necessary -- public members don't
show up on private accessors (unless the type itself is
private, in which case it's not really a public member
to begin with), so all the refactoring features should
simply work as expected for public things (even if we
have to call a private constructor to create the object,
we still declare the variable as the public type and
only use the accessor to call the constructor itself),
and you can't get cross-project refactoring on
non-public members today anyway because they're not
exposed to other projects, so you're not really
"losing" anything by using the private
accessors. That said, we would love to implement this
feature, and it's definitely on the list of features to
investigate for the next version.
We've also done a lot of thinking about the brittleness
of private accessors. We plan to investigate a feature
for this version that will result in private accessors
being automatically updated as your code changes (or at
least when you compile, the actual details aren't
finalized yet). This means that, while refactoring still
won't work for private methods (see above comment about
how it doesn't work today in that situation anyway), at
least you'll get meaningful compile errors when your
private methods change, which you can then fix normally.
The plans for this change are still tentative and we're
not sure yet if it will be doable, but every customer
that asks for this feature makes it more likely to
happen, so please send in your vote on whether you think
this would be useful.