3 Comments

  • 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.



    We really appreciate the feedback. Thank you!

Comments have been disabled for this content.