I'm writing a Junit 4 test class comprising of 5 test methods.
All these 5 test methods have same 10 assertEquals lines of code.
Would it be best practice to move these lines of codes in one method for e.g. public void callAssertions() { .... }
and call this method from all tests?
As matt freake's comment mentions - Calling Junit Assertions via method call, there are differing opinions, but what I would do is separate assertions that are similar in nature.
So for example if you want to assert person's details, I would separate them into an assertPersonDetails() method - and so forth for other assertions. It really depends on the business logic underneath.
I wouldn't recommend separating them all into a generic named method like you suggested callAssertions()
As with all code, you should make sure that every test and every method in your test is readable and comprehensible.
You should have a clear pattern in your top test methods: given X, when Y, then Z. You can extract common code from each of the given/then/when parts, but you should not mix them.
So an assertThatZzzIsConsistent(...) method is OK, if it extracts only from the 'then' part. But an executeYyyAndAssertThatZzzIsConsistent(...) is not OK if it combines the 'when' and 'then' part.
I think that is a neater solution yes. Personally i always keep everything as separate as possible so every test is completely standalone. As long as that is the case it's okay.
Related
I want to test a function in my code. This function calls another function in the same class but in my test I don't want to call it (I don't need it). Somehow, my test always goes into that inner function and makes errors. Is there any means to "skip" the call to that inner function ?
Here's an example :
void function1() {
if(condition == true) {
variable1 = function2()
}
}
Object function2() {
//Do something
return Object;
}
Is there a way to avoid calling function 2 ?
Thank you.
First you should consider fixing those errors thrown from function2().
If however you want to test the function1() isolated then the behavior you are describing is called Test Doubles. One kind of those test doubles is Mocking where you can drive the behavior of a class or a method.
There are frameworks doing this such as Mockito, but of course you can solve that problem on your own not depending on frameworks.
For example if you use Mockito you should end up mocking the function2() method like this
YouClassName mockedClass = mock(YouClassName.class);
when(mockedClass.function2()).thenReturn(new Object()); //you can of course return anything here
Its pretty common to test functions in isolation but in times where are dependencies between objects. If there are no dependencies you should probably consider not using test doubles (unless you are sure what you are doing).
Frameworks such as Mockito offer concepts such as spies. Using a Mockito spy, you can gain full control over which methods get invoked.
But: you only do that for very specific cases.
When you have a hard time testing your production code, then most likely: because you have written hard to test code.
Thus: you could try to use a spy here, but I would rather advice to step back and re-think what exactly you intend to do here.
This question already has answers here:
How do I test a class that has private methods, fields or inner classes?
(58 answers)
Closed 8 years ago.
I have a class that has one public method (cheer for single responsibility principle) except within that method there is a try that lists about 20 method calls. In terms of testing and / or refactoring and testing, how would I go about this? I'm new to java. Looking for a better way to structure and test this code. Any suggestions / pointers to best practices would be appreciated! Thanks!
Just because you have one public method doesn't mean you're following the Single Responsibility Principle. For example, you could write an entire project directly in the main method if you wanted to. That main would have many responsibilities.
What I'd do is test it through the public method if you can. If you can't, that suggests there's to many responsibilities in your class. You should discover these separate responsibilities and move them into other classes with their own public methods and then test the new class separately.
I agree with the previous answer. You should really consider having methods that accept parameters and perform a single action and return the result. If you can't break up your code into smaller segments, then you may add assertions directly to your code without use of a separate unit test class. Here is a link to show you how to add directly to your code.
http://www.deitel.com/articles/java_tutorials/20060106/Assertions.html
Look at the specification for the method. (There is a specification, right?)
Every sentence or part-sentence in the specification that describes one thing that the method does should induce one test case - that is, one method in the test class that includes an assertion. If a sentence talks about behaviour in different scenarios (e.g. if the price field is > 0 then add a line to the statement, otherwise throw an IllegalArgumentException), then it might give you multiple test cases.
But seriously, 20 method calls within one method? That sounds to me like rather a fragile design. Please reconsider it.
I have two tests they are exactly the same... barring two things, they call two separate service calls.. hence when im using mockito i have two seperate expectation and verify lines...
this is what i have done:
#test
TestA {
baseTest("player");
}
#test
TestB {
baseTest("member");
}
BaseTest(type type) {
....
.....
if type(player) {
Mockito.when(player service call)
}
else {
Mockito.when(member service call)
}
// make the call in code
//verify
if(player) {
verify player specific service call...
}
else {
}
}
I think the above is a test smell... just doesnt feel right...
Is there a better way then placing an If statement in my baste test?
Anywhere you see repeated if statements like that, you can use polymorphism. You should make the "player service call" and "member service call" methods abstract in the superclass BaseTestSuper, which will also own the existing BaseTest method..
You should develope your test code independenly and join things when they have sense.
By example. One rule of thumb for initialization code (the first A of Arrange/Act/Assert) is that:
you should write all the Arrange part of a test method in the test.
if your method shares initialization with all the other methods, then put it in a #Setup method
if some test method doesn't share that initialization it's probably because it doesn't fit in that test case.
So my conclusion is:
write independent tests
if they share things you can refactor
but not too much (or in a weird thing like "if"s)!!! Adds complexity, not reuse.
In fact #artbristol answer makes sense: if you are using if's for alternate behaviour consider polymorphism. It's just I'm not sure until which point it's complex for test or not (probable it makes sense if the code is testing a similar class hierarchy).
I would still just implement the 2 test classes separately. Code length and duplication don't really matter for tests, code readability, thoroughness and correctness take priority. In that light, just implement the 2 test cases separately.
In general you should not add any complexity to your tests. First, you can make mistake there (even in simple ifs). Second, your tests are not a documentation anymore, meaning that you can not easily understand what is the scenario of usage and behaviour of the tested class.
So it is a smell. :)
I'm using easymock, and I am mocking my UserService class.
My UserService has a few methods:
boolean canUserLogin(..);
boolean canUserJoinClass(...);
Now some of the methods call each other, and if I am testing method#1 I want to stub/mock methods #2 and methods# 3 that are called in method#1.
What I am confused is, how can I mock parts of a class and leave others to run the actual code?
So I want to actually test UserService.method#1, but mock UserService.method#2 and UserService.method#3 that method#1 calls internally.
By specifying return values for the methods you want mocked; see the easymock docs for examples.
The "Specifying Return Values" section discusses creating return values for mocked methods.
The "Partial mocking" section (towards the bottom) discusses mocking actual classes.
I agree with the docs (and other answers) that this may be an indication of sketchy design. Without further details, it's hard to say how sketchy it is, if it is at all.
You can check some library like Easymock, but I don't sure whether it can do this.
And here is my solution without third-party library. Create a subclass of UserService, and override the method you want to mock.
class SubUserService{
#override
boolean canUserJoinClass(...){
return false;
}
}
But notice the mock method can't be private.
And if this is one real problem you meet, you should refactor you methods to different classes.
I know Mockito supports "spy" on real objects. I could not find an equivalent in Easy Mock. So, I am not sure if you can do this.
Having said that, this is a smell to me. Why do you need to mock it? Is that an indication of the fact that your object is doing too much and hence you need to mock the other interactions?
Also, whenever you need to worry about the implementation of a method (method 1 in this case) i.e. the fact that it calls method2 and method3, especially of the same class, that sounds to me like a encapsulation leaking.
Mocking is intended to be used for dependencies, so you can test in isolation. In this case, you don't have any dependencies, since the methods you are calling are on one class. So I wouldn't use mocking here.
If methods 2 and 3 are so complicated that you want to mock them when testing method 1, then perhaps you should separate them out into their own class(es), so you can easily mock them.
Lets say we have method to test in class A that calls method from class B. To test it we created mock for B and then verify if it was called. Is verify(...) enough for unit test or I need assert actual result of tested method?
Below is simplified example to clarify my concern:
public class StringWriterATest {
StringWriterB b = mock(StringWriterB.class);
#Test
public void stringWriterATest() {
StringBuffer sb = new StringBuffer();
StringWriterA a = new StringWriterA();
a.stringWriterB=b;
a.append(sb);
ArgumentCaptor<StringBuffer> argument = ArgumentCaptor.forClass(StringBuffer.class);
verify(b).append(argument.capture());
assertEquals("StringWriterA", ((StringBuffer)argument.getValue()).toString());
//do we really need this or above is enough for proper unit test of method a.append(sb);
//assertEquals("StringWriterA_StringWriterB", sb);
}
}
public class StringWriterA {
public StringWriterB stringWriterB;
public void append(StringBuffer sb) {
sb.append("StringWriterA");
stringWriterB.append(sb);
}
}
class StringWriterB {
public void append(StringBuffer sb) {
sb.append("StringWriterB");
}
}
Regards,
Max
There is never a need to mock a return value and verify an object at the same time.
Consider this:
StringWriterA is the class under test. Therefore you'll definitely want to use assertions to verify the behavior of this class. In order to do this, you mock out a dependency, StringWriterB.
You do not want to test StringWriterB in your test of StringWriterA, therefore any assertions of StringWriterB interactions in your test are in the wrong place.
You must assume that StringWriterB is behaving as expected. You either want to verify that StringWriterA called StringWriterB correctly (using verify()) or you want to mock its expected behavior and mock the return values.
If you mock, then the verify is implicit since the mocked return value will not be returned if the method is not called.
In your case, StringWriterA.append() does not return any value, so only a verify is even possible. That StringWriterB.append() also works should have a similar verify test in a stringWriterBTest of its own.
Note: It's nice to be explicit with tests. Since test methods are never called outside of a framework, there is never a need to type them out, so you can have much longer method names than in production code methods. A nice convention is:
<underTest>Should<Expected>[When]<Condition>()
i.e.
stringWriterAShouldAppendConstantAndDelegateToStringWriterB()
stringWriterAShouldThrowNullPointerExceptionWhenNullArgument()
When you have test failures in your build (continuous integration), then you don't have to hunt down what went wrong, the method name appears right by the failure and you can read it to know exactly what behavior must be fixed.
In your example, StringWriterB stores no state and the append method could easily be static. In that case then the call is purely a side effect and does not need to be tested.
However, I suspect your real code is much more complex. If there is a of another object accessing StringWriterB then you maye want to mock it out in case there are unexpected calls to it. You also may want to add the verify of B if you expect it to be expanded in the future -- possibly storing state from the append call and having accessors.
One thing to consider is what the purpose of the call to StringWriterA.append() is. If it's job is to append the string StringWriterAStringWriterB then that is what you should be testing and a mock is not necessary. How StringWriterA accomplishes that task is immaterial. If, however, part of its job is to also call the StringWriterB.append() method then a mock may will be necessary unless you want to test StringWriterB in A's test.
My rule of thumb WRT mocks is to use real objects until the wiring for the objects I'm not directly testing gets too hairy or too brittle. If I feel like a good portion of my tests are in actuality testing other objects then mocks would be a good idea.
First of all try to show somebody the test you wrote. It is hard to read in my opinion. You can't really tell from it what behaviour you are testing. A brief intro for you how to make it a bit more readable can be found here How to Write Clean, Testable Code .
Using argument captors is also a smell. Some examples how to avoid it can be found on this tdd blog.
To answer you question, verify is used to verify interactions between classes. It is used to drive the design of your code. The result (if needed) should be specified by a when or given at the beginning of your test.
Further information how to drive your design with mocks (when, given, verify, ...) and how mocks are different to stubs can be found here: Mocks are not stubs. That example uses JMock not Mockito for defining mocks, but it is very similar (it is about the concepts, not the details of implementation and libraries you use).