Are Using Interfaces Soley to Facilitate Stubing and Mocking in Unit Tests Now Obsolete?

后端 未结 4 832
既然无缘
既然无缘 2020-12-29 09:28

In .NET, TypeMock Isolator and Microsoft Moles allow one to isolate any class, property, or method - be it sealed, static, protected or non-virtual. So what was impossible t

相关标签:
4条回答
  • 2020-12-29 09:54

    Not at all. From a purely technical point of view the interfaces are not strictly necessary. The only requirement for a mocking framework to construct a mock is that a method is virtual and the type has an accessible constructor. I utilize it quite a bit when I know that a particular class will not have multiple implementations.

    I prefer doing TDD with a normal Castle Dynamic Proxy based mocking framework. It is all about creating a loosely coupled system with appropriately placed testing seams. Those testing seams could in future become extensibility points. The requirements placed by mocking considerations reinforce good design practices, causing more focused classes to be written.

    0 讨论(0)
  • Irrespective of unit testing coding to interfaces helps provide a loosely coupled system allowing you to slide modules in and out relatively easily be it swapping one for the other or some sort of configuration.

    That aside there are many, my self included, that would say that TypeMock and the like that allow you to mock statics allow for bad practices. Others would say we live in ivory towers and that TypeMock allows you to get on and get things done. I don't hesitate to think that perhaps both are right and wrong depending on your point of view and what you want to achieve. I myself will continue to use interfaces and RhinoMock, NSubstitue or Moq at a push.

    As you can see from these posts Good Design is not Subjective and Design And Testability from 2008 to 2010 it is still a hughly debated subject as you can see from the comments.

    0 讨论(0)
  • 2020-12-29 10:18

    This is indeed an interesting question, which I sometimes heard from testing newbies. In my opinion, Moles/Typemock are not really comparable to mocking frameworks, and they are surely not a replacement. Here are my top arguments for it:

    • While it's worth every penny, Typemock comes with considerable initial license costs (~$800 per seat), why some managers hesitate to invest this amount of money. Moles on the other hand is free, but requires quite some work to set up a Moles assembly and comes with a quite strange 'API', which is very hard to learn - especially if you are totally new to testing.
    • Typemock and Moles are not 'Mocking frameworks' in the strict sense - they are some sort of profilers, which use runtime instrumentation under the hood. Thus, they come with a quite hefty performance impact. I have no concrete figures on that, but from my own experience I'd estimate that instrumented tests are around 100-400% slower (Typemock seeming to be faster than MS Moles)! With a large test battery containing thousands of tests, this may be an impediment in itself.
    • Last not least, the killer argument: A mocking framework forces you not only to use interfaces, but forces you to apply a highly decoupled and maintainable design on your software (along the lines of SOLID). - And remember: It's not the initial writing of the software, that primarily accounts for its costs, but it's the maintenance! - With Typemock or Moles, you basically can do whatever you want, and this really is a bad thing and the main argument against developing with Typemock or Moles.

    Conclusion:

    • If you want to cover a brownfield project with tests, which was not written at all with testability in mind, then you have to use one of Typemock or Moles (in my opinion, Typemock is the better choice).
    • If you're starting a new project (i.e. you're doing a greenfield project), then use a mocking framework (I personally like Moq because of its simplicity) and use MS Moles as a complementary for things you can't have an interface for (e.g. .NET framework types).

    Even Roy Osherove, the lead dev of Typemock, puts it that way (hopefully he's not getting into trouble with his boss because of this): A customer switches to MOQ – and I’m happy

    There's one exception, though: If learning Test-driven development from scratch, it may be beneficial to use Typemock even for new code. This way, you can significantly flatten the TDD learning curve...

    Thomas

    0 讨论(0)
  • 2020-12-29 10:18

    But then we are back to the situation of having added production code complexity for basically the ability to unit test.

    But that's not the reason you do it. You do it because otherwise the code has a hard dependency to an external element. Like a very simple specific implementation of a mail sender.

    You isolate the external functionality behind simple contracts, that makes the rest of your code simpler / not more complex. You very clearly see the dependencies the code has, instead of those being hidden in the internals of the code.

    You now have a simple mechanism to change those dependencies. There is less resistance when you end up needing to modify those contracts, that when the code is all mixed up in a chatty conversation in the internals of the class.

    This is something that's hard to explain in the context of a simple stackoverflow question, specially as it usually takes a very long time for good design concepts to really sink in (if they do ...). I suggest reading about SOLID here.

    Replacing like that with TypeMock has its place. To test legacy code that's not properly design, and maybe a handful other scenarios.

    0 讨论(0)
提交回复
热议问题