Partial-mocking considered bad practice? (Mockito) - mockito

I'm unit-testing a business object using Mockito. The business object uses a DAO which normally gets data from a DB. To test the business object, I realized that it was easier to use a separate in-memory DAO (which keeps data in a HashMap) than to write all the
when(...).thenReturn(...)
statements. To create such a DAO, I started by partial-mocking my DAO interface like so:
when(daoMock.getById(anyInt())).then(new Answer() {
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
int id = (Integer) invocation.getArguments()[0];
return map.get(id);
}
});
but it occurred to me that it was easier to just implement a whole new DAO implementation myself (using in-memory HashMap) without even using Mockito (no need to get arguments out of that InvocationOnMock object) and make the tested business object use this new DAO.
Additionally, I've read that partial-mocking was considered bad practice. My question is: is what I'm doing a bad practice in my case? What are the downsides? To me this seems OK and I'm wondering what the potential problems could be.

I'm wondering why you need your fake DAO to be backed by a HashMap. I'm wondering whether your tests are too complex. I'm a big fan of having very simple test methods that each test one aspect of your SUT's behaviour. In principle, this is "one assertion per test", although sometimes I end up with a small handful of actual assert or verify lines, for example, if I'm asserting the correctness of a complex object. Please read http://blog.astrumfutura.com/2009/02/unit-testing-one-test-one-assertion-why-it-works/ or http://blog.jayfields.com/2007/06/testing-one-assertion-per-test.html to learn more about this principle.
So for each test method, you shouldn't be using your fake DAO over and over. Probably just once, or twice at the very most. Therefore, having a big HashMap full of data would seem to me to be EITHER redundant, OR an indication that your test is doing WAY more than it should. For each test method, you should really only need one or two items of data. If you set these up using a Mockito mock of your DAO interface, and put your when ... thenReturn in the test method itself, each test will be simple and readable, because the data that the particular test uses will be immediately visible.
You may also want to read up on the "arrange, act, assert" pattern, (http://www.arrangeactassert.com/why-and-what-is-arrange-act-assert/ and http://www.telerik.com/help/justmock/basic-usage-arrange-act-assert.html) and be careful about implementing this pattern INSIDE each test method, rather than having different parts of it scattered across your test class.
Without seeing more of your actual test code, it's difficult to know what other advice to give you. Mockito is supposed to make mocking easier, not harder; so if you've got a test where that's not happening for you, then it's certainly worth asking whether you're doing something non-standard. What you're doing is not "partial mocking", but it certainly seems like a bit of a testing smell to me. Not least because it couples lots of your test methods together - ask yourself what would happen if you had to change some of the data in the HashMap.
You may find https://softwareengineering.stackexchange.com/questions/158397/do-large-test-methods-indicate-a-code-smell useful too.

When testing my classes, I often use a combination of Mockito-made mocks and also fakes, which are very much what you are describing. In your situation I agree that a fake implementation sounds better.
There's nothing particularly wrong with partial mocks, but it makes it a little harder to determine when you're calling the real object and when you're calling your mocked method--especially because Mockito silently fails to mock final methods. Innocent-looking changes to the original class may change the implementation of the partial mock, causing your test to stop working.
If you have the flexibility, I recommend extracting an interface that exposes the method you need to call, which will make it easier whether you choose a mock or a fake.
To write a fake, implement that small interface without Mockito using a simple class (nested in your test, if you'd like). This will make it very easy to see what is happening; the downside is that if you write a very complicated Fake you may find you need to test the Fake too. If you have a lot of tests that could make use of a good Fake implementation, this may be worth the extra code.
I highly recommend "Mocks aren't Stubs", an article by Martin Fowler (famous for his book Refactoring). He goes over the names of different types of test doubles, and the differences between them.

Related

Are mocks and stubs implementation details?

I have read that with TDD we should approach the entity (function, class etc.) under test from the perspective of the user/caller of the entity. The gist being focusing on the public "interface". This in turn would drive the design and help reason about the design earlier.
But when we need to introduce mocks and stubs into our tests, isn't that an implementation detail?
Why would/should the "user" care about the other entities that are supposed to be there?
E.g.
How to start writing a test for the PlaceOrder service which should check with the credit card service if the user has enough money? Putting a mock for the credit card service whilst writing a test from the perspective of the PlaceOrder client looks out of place now - because it is an implementation detail; our PlaceOrder may call the credit card for each user or it can simply have a cache with scores provided at the creation time.
It's not clear-cut. As a catch-phrase says: Tests are specifications.
When you use Test Doubles you are, indeed, specifying how your System Under Test (SUT) ought to interact with its dependencies.
I agree that this is usually an implementation detail, but there will typically be a few dependencies of a more architectural character.
A common example is an email gateway. If your SUT should send email, that's an observable side effect that the user (or some other stakeholder) cares about.
While you can (and perhaps should?) also run full systems tests that verify that certain conditions produce real emails that land in certain real mailboxes, such test cases are difficult to automate.
Inserting a Test Double that can take the place of an email gateway and verify that the correct message was delivered to the gateway is not only an implementation detail, but an important part of the overall system. In such cases, using a Test Double makes sense.
Yes, Test Doubles specify behaviour, but sometimes, that's exactly what you want.
How much you should rely on this kind of design is an architectural choice. In addition to sending emails, you might choose to explicitly specify that a certain SUT ought to place a message on a durable queue.
You can create entire systems based on asynchronous messaging, which could imply that it'd be architecturally sound to let tests rely on Test Doubles.
In short, I find it a useful heuristic to use Test Doubles for architectural components, and rely mostly on testing pure functions for everything else.
For something like an order service, I wouldn't let the order service contact the payment gateway. Rather, I'd implement the order service operations as pure functions, and either pass in a payment token as function arguments, or let the output of functions trigger a payment action.
The book Domain Modeling Made Functional contains lots of good information about this kind of architecture.
On the other hand, the book Growing Object-Oriented Software, Guided by Tests contains many good examples of how to use Test Doubles to specify desired behaviour.
Perhaps you'll also find my article From interaction-based to state-based testing useful.
In summary: Tests are specifications. Test Doubles are specifications. Use them to specify the observable behaviour of the system. Try to avoid using them to specify implementation details.
But when we need to introduce mocks and stubs into our tests, isn't that an implementation detail?
Yes, in effect. A bit more precisely, it is additional coupling between your test and the details of your test subject's implementation.
There are two ideas in tension here. On the one hand, we want that our tests are as representative as possible of how our system will actually work; and on the other hand we each of our tests to be an controlled experiment of our implementation, without coupling to shared mutable state.
In some cases, we can disguise some of the coupling by using inert substitutes for our dependency as the default case, so that our implementation classes are isolated unless we specifically opt into a shared configuration.
So for PlaceOrder, it might look like using a default CreditCardService that always answers "yes, the customer has enough money". Of course, that design only allows you to test the "yes" branch in your code - to test a "no" branch, you are necessarily going to need to know how to configure PlaceOrder with a CreditCardService that declines credit.
For more on this idea, see the doctrine of useful objects.
More generally, in TDD we normally take complicated designs that are hard to test and refactor them into a design where something really simple but hard to test collaborates with something that is complicated but easy to test.
But for that to work at all, the components need to be able to talk to each other, and if you are going to simulate that communication in a test you are necessarily going to be coupled to the "implementation detail" that is the protocol between them.
For the case where that protocol is stable, having tests coupled to those details isn't, of itself, a problem in practice. There's coupling, sure, and cost of change, but if the probability of change is negligible then the expected cost of that coupling is effectively nothing.
So the trick is identifying when our tests would require coupling to an unstable implementation protocol, and figuring out how to best mitigate the risk of change.

Asynchronous Programming with OOP in TypeScript

I am having a problem writing clean OOP code, say in TypeScript, while some of my objects contain async methods: what 'ends up' happening is that I am writing static methods, and whichever object or method 'uses' these static methods is 'contaminated' and needs to be converted into a sort of promise itself... I am sure I doing something wrong - is there some architecture trick that I am missing?
Let's take a concrete example: I am writing a Node JS app with a model object of my MongoDB document. Nothing fancy. However, when I use the object's methods in my app, doesn't matter in which class, every method that uses the methods has to be async. And then every method that uses the method that uses the method has to be async as well... etc.
Is there a way to use the MongoDB async operations in such a way as to at least keep up the façade of normal OOP architecture, or is there an entirely new sort of logic I need to learn to write async OOP apps?
Hope I made my question clear,
Async methods don't have to be static, and there really isn't any reason that a program using async operations can't have the same overall structure as one that doesn't.
Async operations are contagious, however. That's known as the red/blue function problem: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/
It's not ideal, but it's the best that can be done without requiring some very special capabilities from the language/system used to implement JS. You can either have threads, which come with their own problems, or you can have some mechanism for copying call stacks around, like Go and upcoming Java project Loom.

How would I make separate duplicated logic in Value Objects

I'm learning DDD (Domain Driven Design) and reading Clean Architecture. I found out about Value Objects and have been reading more about them and have implemented some in my application which could be found https://gist.github.com/Tyler0722/73ec826be814b8e54b9f6ae6ae836409.
Value Objects are created by calling the factory method which performs validation and follows the separation of concerns principle. The problem is I have two Value Objects where the validation logic is duplicated. Username and QuizTitle where the only difference is MAX_LENGTH which violates the DRY principle. I was wondering if anyone knew anyway I could make this DRY.
If you want to remove repetition you must be very careful.
The first question you should ask yourself is
What is the same and what is different?
Maybe you will find the same or similar structure like
check the props
create an error result or a success result
If you found out what you think the same is you have to ask yourself more questions:
Do the things that are (look) the same have different responsibilities?
Do they change for the same or for different reasons?"
These are the questions that are about the single responsibility principle. Sometime things look the same by accident. They look the same but are different, because they change of different reasons. If you eliminate the "duplication" in this case you will have more problems then you solve.
E.g. if you consolidate the validation logic of QuizTitle and Username into one method and later you get a change request for the QuizTitle validation you can easily break the validation behavior of Username. I guess it should not change if the QuizTitle validation changes.
You might also want to read the good article by Martin Fowler about Avoiding Repetition
My suggestion is to not do it. In this case it's just not necessary.
But if you want to do it anyway, you can build a Validation class with static functions. At my work we use Webmozart/Assert and if you take a look at its implementation you will understand what I mean. In my opinion there are very handy. Also you can pass the MAX_LENGHT as an argument.
Well, I agree with Darius Mann, that these value objects have similar business logic is ocasional, if they are different concepts in your app, keep them separated and independently, it is my opinion.

Meta Programming, whats it good for?

So Meta Programming -- the idea that you can modify classes/objects at runtime, injecting new methods and properties. I know its good for framework development; been working with Grails, and that framework adds a bunch of methods to your classes at runtime. You have a name property on a User object, and bamm, you get a findByName method injected at runtime.
Has my description completely described the concept?
What else is it good for (specific examples) other than framework development?
To me, meta-programming is "a program that writes programs".
Meta-programming is especially good for reuse, because it supports generalization: you can define a family of concepts that belong to a particular pattern. Then, through variability you can apply that concept in similar, but different scenarios.
The simplest example is Java's getters and setters as mentioned by #Sjoerd:
Both getter and setter follow a well-defined pattern: A getter returns a class member, and a setter sets a class member's value. Usually you build what it's called a template to allow application and reuse of that particular pattern. How a template works depends on the meta-programming/code generation approach being used.
If you want a getter or setter to behave in a slightly different way, you may add some parameters to your template. This is variability. For instance, if you want to add additional processing code when getting/setting, you may add a block of code as a variability parameter. Mixing custom code and generated code can be tricky. ABSE is currently the only MDSD approach that I know that natively supports custom code directly as a template parameter.
Meta programming is not only adding methods at runtime, it can also be automatically creating code at compile time. I.e. code generating code.
Web services (i.e. the methods are defined in the WSDL, and you want to use them as if they were real methods on an object)
Avoiding boilerplate code. For example, in Java you should use getters and setters, but these can be made automatically for most properties.

Using object's setter to trigger data updates, best practices

I have an object that gets instantiated in a linq to sql method. When the object fields are being assigned, i want to check a date field and if it is an old date, retrieve data from another table and perform calculations before continuing with assigning this object.
Is there anything wrong with triggering such an event through the property setter Or should I independently check the date through some service and make the changes if necessary at some point aftwewards?
There's nothing wrong with doing some logic from within your setters, but you should be careful about just how much logic you put within your setters. One of the fundamental problems of setters is that since they act like attributes, but have backing code, it's easy to forget that there are potentially some non-trivial actions going on behind the scenes.
This sort of thing can cause problems if you have accessors which use accessors which use accessors; you can rapidly end up causing unexpected performance problems. Generally, it's a good idea to keep the actions of setters (or getters, for that matter) to a relatively small set of actions. For example, validation can work perfectly fine in a setter, but I'd generally advise against doing validation against external resources, because of two things: first, resource delays can cause problems with expected access speed, and secondly, the number of external resource accesses can destroy your performance.
Generally, the rule is this: keep it simple. It's not unreasonable to do complicated things in a setter, but if you do, it's really important to understand the consequences of all of the actions you'll be causing, and it's EXTREMELY important to document what it does extremely well, so the next guy (or girl) to use the code doesn't just try to naively use the accessor and end up causing massive resource contention issues unexpectedly.
Half the point of using setters instead of, say, public fields, is to be able to trigger events associated with setting certain data.
Keyword: associated. If you're just using the setter as a "convenient" time to do some other stuff because it happens to work, you're doing it wrong. If setting this value requires other work to be done, then by all means, use the setter to do it.

Resources