I'm developing a new project. This is what has been done until now:
A technical design.
The model classes (data classes).
All the interfaces in the project (but no implementations yet).
Next thing I wanna do is implementing the methods from the skeleton (the high level methods) down to the nested objects. Nevertheless, I want to create a unit test for each method before I write the implementation. There won't be any problem to implement the high level methods first, because I'm going to work with interfaces and bind the concrete implementation only in an external Java configuration file using DI.
The first method I'm gonna implement is called lookForChanges() and it both accepts and returns void. This method is called by Spring's scheduler (#Scheduled), and it manages the whole process: it retrieves data from the DB, retrieves data from a web service, compares them, and if there were any changes then it updates the database and sends a JMS message to a client. Of course, it doesn't do all those things by itself but it calls the relevant classes and methods.
So the first problem I'd had is how to create a unit test to a void method. In all tutorials always the tested methods accept parameters and return a result. I've found an answer for that in this question. He says that even if there's no result to check, at least one can make sure that the methods inside the tested method were called and with the correct order of parameters.
I sort of liked this answer, but the problem is that I'm working TDD so in contast to the guy who asked this question, I'm writing the test before implementing the tested method, so I don't know yet which methods and in what order it will use. I can guess, but I will only be sure about that once the method will have been already implemented.
So, how can I test a void skeleton method before I implement it?
So the first problem I'd had is how to create a unit test to a void method.
A void method implies collaborators. You verify those.
Example. Suppose we needed a task that would copy System.in to System.out. How would we write an automated test for that?
void copy() {
// Does something clever with System.in and System.out
}
But if you squint a little bit, you'll see you really have code that looks like
void copy() {
InputStream in = System.in;
PrintStream out = System.out;
// Does something clever with `in` and `out`
}
If we perform and extract method refactoring on this, then we might end up with code that looks like
void copy() {
InputStream in = System.in;
PrintStream out = System.out;
copy(in, out);
}
void copy(InputStream in, PrintStream out) {
// Does something clever with `in` and `out`
}
The latter of these is an API that we can test - we configure the collaborators, pass them to the system under test, and verify the changes afterwards.
We don't, at this point, have a test for void copy(), but that's OK, as the code there is "so simple that there are obviously no deficiencies".
Notice that, from the point of view of a test, there's not a lot of difference between the following designs
{
Task task = new Task();
task.copy(in, out);
}
{
Task task = new Task(in, out);
task.copy();
}
{
Task task = Task.createTask();
task.copy(in, out)
}
{
Task task = Task.createTask(in, out);
task.copy();
}
A way of thinking about this is: we don't write the API first, we write the test first.
// Arrange the test context to be in the correct initial state
// ???
// Verify that the test context arrived in final state consistent with the specification.
Which is to say, before you start thinking about the API, you first need to work out how you are going to evaluate the result.
Same idea, different spelling: if the effects of the function call are undetectable, then you might as well just ship a no-op. If a no-op doesn't meet your requirements, then there must be an observable effect somewhere -- you just need to work out whether that effect is observed directly (inspecting a return value), or by proxy (inspecting the effect on some other element in the solution, or a test double playing the role of that element).
OK so now I can pass params to the method for testing it, but what can I test?
You test what it is supposed to do.
Try this thought experiment - suppose you and I were pairing, and you proposed this interface
interface Task {
void lookForChanges();
}
and then, after some careful thought, I implemented this:
class NoOpTask implements Task {
#Override
void lookForChanges() {}
}
How would you demonstrate that my implementation doesn't satisfy the requirements?
What you wrote in the question was "it updates the database and sends a JMS message to a client", so there are are two assertions to consider - did the database get updated, and was a JMS message sent?
The whole thing looks something like this
Given:
A database with data `A`
A webservice with data `B`
A JMS client with no messages
When:
The task is connected to this database, webservice, and JMS client
and the task is run
Then:
The database is updated with data `B`
The JMS client has a message.
It looks like what you suggest is an end-to-end test.
It does look like one. But if you use test doubles for these collaborators, rather than live systems, then your test is running in an isolated and deterministic shell.
It's probably a sociable test - the test doesn't know or care about the implementation details of the system under test in the when clause. I make no claims that the SUT is one-and-exactly-one "unit".
I have to see the implementation of foo first. Am I wrong?
Yes - you need to understand the specification of foo, not the implementation.
Related
I've inherited a Struts2 project which needs some functionality addition. When I ran into de code to guess how the previous guy did things, I found out that if he wants a class to instantiate only once when the Tomcat server starts (because it has to read heavy loads of data from disk, but only once to get its config, for instance), he did this in the following way:
public class ExampleClass {
public ExampleClass(){//Read files and stuff to initialize}
public Object method(Object[] args){//The job to do}
}
And then, in the struts action which uses it he instantiates it this way:
public class SomeAction extends ActionSupport {
ExampleClass example = new ExampleClass()
public String execute() {
//Do stuff every time the action is called
Object result = example.method(args);
// Do stuff with results
}
}
I know from servlet times that this does the trick, however, I feel like the guy who handled this before was as inexperienced in Struts2 as I am, so here comes my question:
Is this the proper way to do so according to style recommendations and best practices? Does struts2 provide a more controlled way to do so?
I found some answers related to simple parameters here, but I'm not sure if this is the proper way for objects like those? What would happen if ExampleClass instance is really heavy? I don't want them to be copied around:
How to set a value in application scope in struts2?
Some background about ExampleClass: When the constructor is called, it reads large sets of files and extracts it's configurations from them, creating complex internal representations.
When method() is called, it analyzes it's parameters using the rules, and outputs results to the user. This process usually takes seconds, and doesn't modify the previously initialized rule values.
This is running in Tomcat 7, however, I'm planning to upgrade to Tomcat 8.5 when everything is in place. I'd like to know if there are known issues about this regarding to this setup aswell (there are no other incompatibilities in the code).
BTW: He's not checking if ExampleClass is broken or anything like that, this definetly looks like a recipe to disaster xD. In fact, If I remove the source files, it is still trying to execute the method()... Poor soul...
Ideally, I need a way to instantiate all my application-level objects on start-up (they're the application itself, the rest is just a mere interface) in a way that if they fail Struts2 will tell Tomcat not to start that war, with the corresponding error logging and so on.
If Struts2 doesn't support this, which is the commonly accepted work-around? Maybe some Interceptor to check the object status and return to a error page if it hasn't been correctly instantiated? Execute a partial stop of tomcat from within?
All the objects of this project are thread safe (the only write operation inside them is performed on initialization), but I'd like to know best practices for Struts2 when objects are not so simple. What happens if a user can actually break one? (I know I should by any means avoid that, and I do, but mistakes happen, so I need a secure way to get through them, and get properly alerted, and of course I need a way to reinstantiate it safelly or to stop the whole service).
Right now, I can manually execute something like:
public class SomeAction extends ActionSupport {
ExampleClass example = new ExampleClass();
private boolean otherIsBuildingExample = false;
public String execute() {
if(otherIsBuildingExample) return '500 error';
if(example==null || example.isBroken()){
otherIsBuildingExample = true;
example = new ExampleClass();
otherIsBuildingExample = false;
}
Object result = example.method(args);
// Do stuff with results
}
}
Indeed, this would be cleaner with Interceptors, or so, however, this sounds like a pain in the *** for concurrency, specially taking into consideration thay example takes several seconds to start, and that more requests can come, so more concerns to take into consideration, like: what if two people call if(otherIsBuildingExample) and the second one gets the value before the first one performs otherIsBuildingExample=true? Nothing good... If the class is simple enough, both will instantiate and the slower one will prevail, but if one instantiation blocks the other's resources... well, more problems.
The only clean solution I can think of is to make ExampleClass robust enough so you can repare it using its own methods (not reinstantiating) and make those thread safe in the common way (if 10 people try to repair it, only one will proceed, while the others are just waiting for the first to end to continue, for instance).
Or maybe everytime you call execute() you get a copy of example, so no worries at all about this?
I'm digging into struts documentation
Thanks in advance.
I'm working in a Project with a Service class and some sort of a Client that acts as a facade (don't know if it's the right term in the Design Patterns's world, but I'll try to make myself clear). Service's methods can be very expensive as they may be communicating with one or more databases, long checkings and so on, so every Client method should call one and only one Service method.
Service class structure is something like
public class Service {
public void serviceA(){...}
public SomeObject serviceB(){...}
// can grow in the future
}
And Client should be something like
public class Client {
private Service myService; // Injected somehow
public void callServiceA() {
// some preparation
myService.serviceA();
// something else
}
public boolean callServiceB(){...}
}
And in the test class for Client I want to have something like
public class ClientTest{
private Client client; // Injected or instantiated in #Before method
private Service serviceMock = mock(Service.class);
#Test
public void callServiceA_onlyCallsServiceA() {
client.callServiceA();
????
}
}
In the ???? section I want something like verifyOnly(serviceMock).serviceA() saying "verify that serviceMock.serviceA() was called only once and no other method from the Service class was called". Is there something like that in Mockito or in some other mocking library? I don't want to use verify(serviceMock, never()).serviceXXX() for every method because, as I said, Service class may grow in the future and I will have to be adding verification to every test (not a happy task for me) so I need something more general.
Thanks in advance for your answers.
EDIT #1
The difference between this post and the possible duplicate is that the answer adds boiler plate code which is not desired in my case because it's a very big project and I must add as few code as posible.
Also, verifyNoMoreInteractions can be a good option even when it's discouraged for every test, no extra boiler plate code needed.
To sumarize, the possible duplicate didn't solved my problem.
There's another issue: I'm writing test for code made by another team, not following a TDD proccess myself, so my test should be extra defensive, as stated in this article quoted in the mockito documentation for verifyNoMoreInteractions. The methods I'm testing are often very longs so I need to check that the method under test calls ONLY the necesary services and no other (because they're expensive, as I said). Maybe verifyNoMoreInteractions is good enough for now but I'd like to see something not being discouraged for every test by the very same API creator team!
Hope this helps to clarify my point and the problem. Best regards.
verify(serviceMock, times(1)).serviceA();
verifyNoMoreInteractions(serviceMock);
From Mockito's javadoc on verifyNoMoreInteractions:
You can use this method after you verified your mocks - to make sure that nothing else was invoked on your mocks.
Also:
A word of warning: Some users who did a lot of classic, expect-run-verify mocking tend to use verifyNoMoreInteractions() very often, even in every test method. verifyNoMoreInteractions() is not recommended to use in every test method. verifyNoMoreInteractions() is a handy assertion from the interaction testing toolkit. Use it only when it's relevant. Abusing it leads to overspecified, less maintainable tests.
The only way you can reliably verify that your service is only ever called once and only once from the method you specify and not from any other method, is to test every single method and assert that your serviceA method is never invoked. But you're testing every other method anyway, so this shouldn't be that much of a lift...
// In other test cases...
verify(serviceMock, never()).serviceA();
While this is undesirable from a code writing standpoint, it opens the door to separating out your service into smaller, more responsible chunks so that you guarantee that only one specific service is called. From there, your test cases and guarantees around your code become smaller and more ironclad.
I think what you are looking for is the Mockito.verify and Mockito.times
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
verify(mockObject, atLeast(2)).someMethod("was called at least twice");
verify(mockObject, times(3)).someMethod("was called exactly three times");
Here another thread with the same question:
Mockito: How to verify a method was called only once with exact parameters ignoring calls to other methods?
So let's say I have a simple activity as follows. Assume all of the the lifecycle events etc. are correctly created there's no exception in creating an activity.
public class ButtonClickActivity extends Activity implements OnClickListener {
... onCreate etc. ...
#Override
public void onClick(View v) {
logInfo();
}
protected void logInfo() {
Log log = new Logger();
log.log('foo');
...
}
}
How exactly would you test that the onClickMethod calls on callMyOtherMethod? How also would you test that logInfo makes a new Logger and .log('foo')? Let's assume you have all frameworks at your disposal.
I've tried to use Robolectric (which is fine for high level testing, but really doesn't seem to let you get down into detail like to test if a method calls another method).
It seems that you have to use that in conjunction with a mocking framework / injection in order to verify at least injected object behavior. It doesn't to be able to test 'new Construction' so you're forced to use a factory always for every single object, even for objects you use from other frameworks etc.
I've given a shot with JMockIt (which allows you to verify every single new construction etc.) but it seems there is a problem there also with ByteCode manipulation and it basically will fail if it tries to rewrite bytecode for Android Activities and Views especially, along with other problems.
So my question for folks is what strategy have they been going with other than 'it's a implementation detail' or 'doesn't need to be tested'? I'm sure of course you don't want to test every little detail method call but letting important method calls go unverified doesn't seem like a good solution either.
I am writing a Socket Application in Java, where a server is taking messages from an eventsource and sending notifications to connected users, depending on the eventtype.
Now I am about to write some JUnit tests for the Server...
JUnit (in eclipse automatically suggests) to implement tests for all public methods and I see the necessity for it. The server class has a public method bufferEvent..., but then the events are handled in private methods and there is not even a method, which returns the number of buffered messages.
So the Server doesn't have public methods to verify the result.
I think the problem can be generalized:
How can I test public methods, where the result cannot be verified with public methods( no getter etc.)
I want to avoid writing additional methods just for testing. Is there a workaround, or best practise to test those things?
Thanks in advance
You should make a constructor that allows you to insert mocks or spies for the collaborators.
For example, you server would have a constructor Server(List<Buffer> buffer). Only used for testing. Then you can add the buffer in the unit test, and assert that modifications are made to that buffer.
List is easy enough to replace with a object you create in the test. If you want more advanced stuff, have a look at a mocking framework like Mockito.
For example you create a mock for a Socket. You'd get Socket = mock(Socket.class. You insert in in the constructor Server(List<Buffer> buffer, Socket socket). Then after you have called whatever function you want to test, you can verify behavior using for example verify(socket).send("yourMessage") to see if the server used the method send with parameters "yourMessage".
For example this Plugins class requires some plugins in it's constructor. To test its the mocks are created, inserted and then verified in this test class like this: verify(proxyServerPlugin).proxyServer(config);.
See the Mockito for more examples.
You could check the negative test case. There is no return from the service but maybe there is an exception which is thrown by the service:
#Test
public void testServerService(){
try{
myServer.service();
Assert.assertTrue(true);
}catch(Exception ex){
Assert.fail("anything goes wrong");
}
}
Otherwise in such cases I write something like this:
#Test
public void testServerService(){
myServer.service();
Assert.assertTrue(true);
}
so I have at least on assertion to check if the process runs without problems.
btw I think you are right. writing new functionality just to verify Junit testcases is very bad practice.
What do think about adding a Logger, with it's own Level TEST , loggin important values at the end of the methods and having a stream to A testclass.
I have a question regarding unit test.
I am going to test a module which is an adapter to a web service. The purpose of the test is not test the web service but the adapter.
One function call the service provide is like:
class MyAdapterClass {
WebService webservice;
MyAdapterClass(WebService webservice) {
this.webservice = webservice;
}
void myBusinessLogic() {
List<VeryComplicatedClass> result = webservice.getResult();
// <business logic here>
}
}
If I want to unit test the myBusinessLogic function, the normal way is to inject an mocked version of webservice with getResult() function setup for some predefined return value.
But here my question is, the real webservice will return a list of very completed classes each with tens of properties and the list could contain hundreds or even thousands of element.
If I am going to manually setup a result using Mockito or something like that, it is a huge amount of work.
What do people normally do in this scenario? What I simply do is connect to the real web service and test again the real service. Is something good to do?
Many thanks.
You could write the code to call the real web service and then serialize the List<VeryComplicatedClass> to a file on disk and then in the setup for your mock deserialize it and have mockwebservice.getResult() return that object. That will save you manually constructing the object hierarchy.
Update: this is basically the approach which Gilbert has suggested in his comment as well.
But really.. you don't want to set up a list of very completed classes each with tens of properties and the list could contain hundreds or even thousands of element, you want to setup a mock or a stub that captures the minimum necessary to write assertions around your business logic. That way the test better communicates the details that it actually cares about. More specifically, if the business logic calls 2 or 3 methods on VeryComplicatedClass then you want the test to be explicit that those are the conditions that are required for the things that the test asserts.
One thought I had reading the comments would be to introduce a new interface which can wrap List<VeryComplicatedClass> and make myBusinessLogic use that instead.
Then it is easy (/easier) to stub or mock an implementation of your new interface rather than deal with a very complicated class that you have little control over.