No, I find that TDD generally encourages good design. Things which are easily testable are often easy to use in production too... because when coming up with a test, you think, "What would I like to do next?" and then make it work.
When practising TDD you are forced to think through the 'use cases' for an API, how the programmer is going to use the classes/methods and you will end up with a very usable framework. If you have to create a hundred FooFactory
and BarAuthenticator
s, or the API is becoming 'ultra modular' like you say, you will likely pick up on that while writing your test code and think about how to simplify it.
As for parameters and dependency injection - I usually find that dependencies become a lot clearer using TDD. They're usually constructor arguments rather than method arguments, but making it clear that an API implementation needs an authenticator, a source of randomness etc. is useful in understanding what it's doing. You can be sure that the code isn't going to hit the network or a remote database somewhere because it's hiding these things in its implementation. These kind of hidden details are what makes an API hard to use in a test environment.
Note that when dependencies are part of the constructor call, it's not part of the interface that class may implement - the dependencies within an interface are usually hidden, but TDD means that the implementation exposes them in an obvious way.
A good source of information about dependency injection and TDD can be found on the Google Testing Blog. Pay particular attention to the posts by Miško Hevery or watch some of his videos on Youtube: Don't Look For Things and more.