Prefer Fakes over Mocks
41–50 of 125 posts
Re: Prefer Fakes over Mocks
#42Earlier quoted context omitted.
Because they don't just implement a part of the interface (just one store method, or just one of two load methods). They try to create a fully functional fake of the original class. In this case instead of storing the blobs via a REST interface or a database connection, it just keeps it in memory. So it should mostly behave like the real implementation, but is not suitable for production, as it doesn't persist the da…
>> .. fully functional fake of the original class. So they are coupled to the implementation of the object in any case!
Re: Prefer Fakes over Mocks
#43Earlier quoted context omitted.
Because they don't just implement a part of the interface (just one store method, or just one of two load methods). They try to create a fully functional fake of the original class. In this case instead of storing the blobs via a REST interface or a database connection, it just keeps it in memory. So it should mostly behave like the real implementation, but is not suitable for production, as it doesn't persist the da…
> Because they don't just implement a part of the interface (just one store method, or just one of two load methods). They try to create a fully functional fake of the original class. So shouldn't fakes have their own tests as well? Mocks don't need tests (at least in C# with a framework) because no new class is ever written. Anyway most of these issues are inherently linked to the nature of OOP and are a direct trad…
In one case you create the class on your own, in the other case the mocking framework does that for you on the fly. With both approaches you can do very basic or very complicated things.
Or do you have a rule in your company that every class needs a test? Maybe this rule is the problem.
Re: Prefer Fakes over Mocks
#44It seems to me that a Fake is really a Mock, and Mocks became this unholy dynamic framework stuff. I'm not a fan of dynamic mocks where the test code has the mocked implementation because it is super brittle. Instead, a "fake" (i.e. a mock as I understood them) is an alternatively implementation of an interface. There are a lot of really good "fakes" out there. Fake file system which lets you simulate disk failures.…
Re: Prefer Fakes over Mocks
#45A tangent, and somewhat philosophical: is "The primary purpose of software testing" really "to detect any potential defects in a program before it reaches its intended consumers"? I would argue that whilst that is a commonly held belief, and certainly true for some tests of business logic, the main value and reason for testing is to allow developers to confidently make changes to existing code. In my experience user…
Re: Prefer Fakes over Mocks
#46Even more important, IMO, regardless of whether you're mocking or faking, is to not mock or fake objects that you own. Only mock/fake truly external dependencies. The nice property you get with this is true tests of integration and interoperability between your modules, that are actually calling into each other. Only at the leaf nodes is anything mocked or faked, and that's when it leaves your ownership.
Re: Prefer Fakes over Mocks
#47Even more important, IMO, regardless of whether you're mocking or faking, is to not mock or fake objects that you own. Only mock/fake truly external dependencies. The nice property you get with this is true tests of integration and interoperability between your modules, that are actually calling into each other. Only at the leaf nodes is anything mocked or faked, and that's when it leaves your ownership.
Also, in dynamic languages, you might even have tests that don’t break when you change (or sometimes even delete) the dependency because the mock was correct. That leads to a false sense of confidence.
Re: Prefer Fakes over Mocks
#48The core reason I find OOP to be superior for most classes of business application development in general—and web development in particular—is that external dependencies and other high cost interfaces can be delegated to their own method or instance variable then called. In general, I avoid inheritance if there is a way to approach a problem with composition, but testing via fakes are much more reliable to make by inheriting the original class and overriding a method or setting a default initialization parameter then calling the rest of the constructor. This takes the pain out of so many parts of testing that it's truly hard to understate.[0]
For example, say a library has a class that calls out to a third party service like S3 and an instance of that class is used in a business object in order to persist data. By introducing a fake that inherits from the library's class but overrides it's persistence method to effectively be a noop the rest of the validation, calculation, and other side effects that the instance does is conserved without the downside of waiting on a network call. It's not perfect, for example it could miss validation or side effects that only exist on the external service (e.g., S3 could change a mime type based on some crummy AWS logic) but it's a hell of a lot better than a mock that constantly lies to you about what its done. Furthermore, it's actually extremely simple to code up, unlike pure fakes that need to return hard coded values for certain method calls.
I know that something akin to this is theoretically possible in functional languages, but I've found that in practice it's more difficult. Though I appreciate other areas where functional languages shine, including situations with testing.
It's kinda hard to discuss because it really depends on so much context and good judgement and I've seen truly great development teams use languages like Scala in situations where I would have used Python with Numpy / Cython for speed. So don't take this as some hard and fast pronouncement. Just the general observations of someone that's been coding for decades and is reasonably well paid.
[0] I think the primary reason that I prefer integration testing over unit testing is that I've adapted to its shortcomings by the above approach.
Re: Prefer Fakes over Mocks
#49Not particularly convincing. Mocks work well because you can quickly define them in a given unit test and forget about it. I can see fakes being useful in certain cases, but only just in certain cases. Could be my inexperience with C#, but it didn't do justice describing the point in code samples.
> Mocks work well because you can quickly define them in a given unit test and forget about it. They do, yes. But: * the mock syntax is complex and verbose. e.g. "repo.Setup(x => x.Method(It.IsAny (), It.IsAny >())) .ReturnsAsync(() => ...." is not the easiest syntax. The syntax for a fake is just regular old "class FakeFoo: IFoo" with trivial method implementations and no library needed to make it work. * the mock s…
A trivial mock implementation is less complex than what OP refers to as “fakes”.
Re: Prefer Fakes over Mocks
#50I'm a little surprised this article and none of the contents here at the time of this writing mentioned inheritance. The core reason I find OOP to be superior for most classes of business application development in general—and web development in particular—is that external dependencies and other high cost interfaces can be delegated to their own method or instance variable then called. In general, I avoid inheritance…
> I know that something akin to this is theoretically possible in functional languages, but I've found that in practice it's more difficult.
Could you explain what you think is hard about it?