Naming convention for classes in test code - java

Assume I have classes ClassX in production code (src/main/java) and ClassXTest in test code (src/test/java). In some test methods I want to tamper what one of the methods of ClassX returns, so I override ClassX and its method. I do not want to use any mocking frameworks or this class to be anonymous. Is there any naming how such classes should be named?

Personally, I would call these classes: ClassXTestImpl
It's not the greatest naming convention in the world, but it makes it obvious that it is test code and is not expected to be used by the production code. You could also make it a private inner class of the test class in which it is being used, then it wouldn't even be accessible by you production code.
Generally, I don't like calling things Impl, but in this case, the ClassX part will define what the class actually does and the TestImpl bit is just to mark it as a test implementation.
An aside about partial mocking:
I know you said that you didn't want to use mocking frameworks, but if you're replacing method1 in order to make method2 easier to test and both methods reside in the same class, then what you're doing is a form of partial mocking, whether you do it with a framework or not. It's difficult to find documentation for Partial Mocking that isn't linked to a particular framework, so I'll provide EasyMock's documentation but point out that most mocking frameworks support this kind of mocking.

These classes are called "test-specific subclasses" and there doesn't seem to by any naming convention. http://xunitpatterns.com/Test-Specific%20Subclass.html gives some examples of overriding classes that are under tests.

Related

Can we changed the access specifier of a method from private to default just for the sake of method level unit testing

I could find many questions/answers on why a method should not make it public. but I could not find anything specific to "default" in Java.
'default', i.e., the absence of a modifier, means package private in Java. Only classes in the same package can access it. Sometimes it is desirable to test an internal method meant for private use of that class in a unit test separate from the rest of that class in order to cover all code paths with clear, concise, and simple tests. When you do this (and the result is cleaner test code that can be maintained with more ease) it is fine to mark that method as package private.
This is not an uncommon strategy. Because the only classes who can use this method must reside in the same package, you still have plenty of control over its use.
Personally I would recommend only doing this for static utility methods that do not depend on the state of their parent class. It is also a very useful technique for testing static methods in abstract classes.
Note that in some cases the need to test private methods may point to the need to break out that part of the class into a separate class instead. This discussion shows some of the common standpoints varying from strict OOP adherence to pragmatism. You often have the possibility to break out that method and make it into a proper public static utility, but that doesn't always make sense, and it doesn't necessarily lead to easier maintained code.
UnitTests are not about testing code, they are about testing public observable behavior, that is: return values and communication with dependencies.
Public observable does not necessarily imply public methods but usually is. We simply test the Methods that other code would call when using the current unit as dependency.
Non public methods (that are not meant to be called by other code) are implementation detail that contributes to the units behavior. Therefore they are testes implicitly.
Keep in mind, that a unit is not connected to a class or a method.
It might even be a group of classes behind a single class acting as "entry point".
A unit is all the code that may change for the same (non technical) reason, a change in the business requirements.
The point here is that implementation details may change while the desired behavior (and thus the UnitTest) does not change. We do such changes to improve the code design (resolve code duplication, apply design patterns and alike). We call them refactoring (This is the third phase in the Test Driven Developement micro cycle). Such a refactoring is exactly the time when we need UnitTest most since when we not change them then they guarantee that the desired behavior of the tested code still exist.

what is the advantage of using #VisibleForTesting? [duplicate]

This question already has answers here:
How do I test a class that has private methods, fields or inner classes?
(58 answers)
Closed 5 years ago.
Who has a solution for that common need.
I have a class in my application.
some methods are public, as they are part of the api,
and some are private, as they for internal use of making the internal flow more readable
now, say I want to write a unit test, or more like an integration test, which will be located in a different package, which will be allowed to call this method, BUT, I want that normal calling to this method will not be allowed if you try to call it from classes of the application itself
so, I was thinking about something like that
public class MyClass {
public void somePublicMethod() {
....
}
#PublicForTests
private void somePrivateMethod() {
....
}
}
The annotation above will mark the private method as "public for tests"
which means, that compilation and runtime will be allowed for any class which is under the test... package , while compilation and\or runtime will fail for any class which is not under the test package.
any thoughts?
is there an annotation like this?
is there a better way to do this?
it seems that the more unit tests you write, to more your inforced to break your encapsulation...
The common way is to make the private method protected or package-private and to put the unit test for this method in the same package as the class under test.
Guava has a #VisibleForTesting annotation, but it's only for documentation purposes.
If your test coverage is good on all the public method inside the tested class, the privates methods called by the public one will be automatically tested since you will assert all the possible case.
The JUnit Doc says:
Testing private methods may be an indication that those methods should be moved into another class to promote reusability.
But if you must...
If you are using JDK 1.3 or higher, you can use reflection to subvert the access control mechanism with the aid of the PrivilegedAccessor. For details on how to use it, read this article.
Consider using interfaces to expose the API methods, using factories or DI to publish the objects so the consumers know them only by the interface. The interface describes the published API. That way you can make whatever you want public on the implementation objects and the consumers of them see only those methods exposed through the interface.
dp4j has what you need. Essentially all you have to do is add dp4j to your classpath and whenever a method annotated with #Test (JUnit's annotation) calls a method that's private it will work (dp4j will inject the required reflection at compile-time). You may also use dp4j's #TestPrivates annotation to be more explicit.
If you insist on also annotating your private methods you may use Google's #VisibleForTesting annotation.
An article on Testing Private Methods lays out some approaches to testing private code. using reflection puts extra burden on the programmer to remember if refactoring is done, the strings aren't automatically changed, but I think it's the cleanest approach.
Or you can extract this method to some strategy object. In this case you can easily test extracted class and don't make method public or some magic with reflection/bytecode.
Okay, so here we have two things that are being mixed. First thing, is when you need to mark something to be used only on test, which I agree with #JB Nizet, using the guava annotation would be good.
A different thing, is to test private methods. Why should you test private methods from the outside? I mean.. You should be able to test the object by their public methods, and at the end that its behavior. At least, that we are doing and trying to teach to junior developers, that always try to test private methods (as a good practice).
I am not aware of any such annotation, however the following may be of value: unit testing private methods
or the following: JMockit
You can't do this, since then how could you even compile your tests? The compiler won't take the annotation into account.
There are two general approaches to this
The first is to use reflection to access the methods anyway
The second is to use package-private instead of private, then have your tests in the same package (but in a different module). They will essentially be private to other code, but your tests will still be able to access them.
Of course, if you do black-box testing, you shouldn't be accessing the private members anyway.
We recently released a library that helps a lot to access private fields, methods and inner classes through reflection : BoundBox
For a class like
public class Outer {
private static class Inner {
private int foo() {return 2;}
}
}
It provides a syntax like :
Outer outer = new Outer();
Object inner = BoundBoxOfOuter.boundBox_new_Inner();
new BoundBoxOfOuter.BoundBoxOfInner(inner).foo();
The only thing you have to do to create the BoundBox class is to write #BoundBox(boundClass=Outer.class) and the BoundBoxOfOuter class will be instantly generated.
As much as I know there is no annotation like this. The best way is to use reflection as some of the others suggested. Look at this post:
How do I test a class that has private methods, fields or inner classes?
You should only watch out on testing the exception outcome of the method. For example: if u expect an IllegalArgumentException, but instead you'll get "null" (Class:java.lang.reflect.InvocationTargetException).
A colegue of mine proposed using the powermock framework for these situations, but I haven't tested it yet, so no idea what exactly it can do. Although I have used the Mockito framework that it is based upon and thats a good framework too (but I think doesn't solve the private method exception issue).
It's a great idea though having the #PublicForTests annotation.
Cheers!
I just put the test in the class itself by making it an inner class:
https://rogerkeays.com/how-to-unit-test-private-methods

Use of an interface in unit tests

Why is it advised to use an interface whilst carrying out unit tests using the Mockito framework?What exactly is the use of an interface in unit testing?
There are two reasons: one theoretical, and one practical.
Theory
When working with a mock, you are providing a test double of a component that exists (or will exist) elsewhere in your application; when stubbing you are simulating the responses that the real implementation would have, and when verifying you're doing so against the class's external interface. This makes it very important to have a clear definition of what successful implementors of the interface should be doing and how they should be behaving, regardless of the current implementation: you're providing a different implementation.
Though you could document your implementation's contract method-by-method on the concrete class itself, another method of documenting and formalizing the general contract of the component is to extract an interface. Though I'm no proponent of prospective work (see YAGNI), doing so also makes it clearer if you were to partially or entirely replace your current concrete implementation with another implementation—at which point you would have three implementations of the interface including the mock, and might want to write a test purely against the interface and pass each implementation in separately for verification/validation between them.
Practice
Internally, Mockito dynamically creates your test double by generating a subclass of the class you're trying to test. This means that your mock can only override behavior that a normal subclass can override, and that can make Mockito ill-suited for private classes, encapsulated nested or inner classes, and final classes. In addition, for similar reasons, you will find yourself unable to mock static methods, final methods, and some private or protected methods (particularly wherever which the compiler generates synthetic methods). Because of Mockito's syntax and dynamic nature, Java can't warn about or enforce these rules at compile time, and Mockito can't always detect violations at runtime.
However, when mocking interfaces rather than concrete implementations, Mockito can avoid much of this trouble. Interfaces have no internal method visibility restrictions or final methods, and the types themselves are necessarily public and non-final. So, from a practical standpoint, there are advantages in simplicity and ease of work that come with interfaces but not concrete classes.

Is it OK to make a private method to non-private just because to make it easier for testing?

We are maintaining some legacy code and we are adding tests for them.
In order to write tests easier, we will extract some code into methods(which will be private be default), then writing tests for them. Since they are private, it's hard to invoke them, so what we did is: remove the "private" keyword, make it "non-private", then write tests.
But it makes some methods non-private which are supposed to be "private". Is it OK to do this, or is there any better solutions?
Update:
I think I'd better to provide some more background:
The code is very complicated and not good, and has nearly no tests. Writing tests for public methods are not possible since they have lots of hard-coded external dependencies and which are not be mocked.
We need to fix some bugs, but without tests we can't do it. So we first extract some related code to some methods, add tests for them, then fix bugs.
Since the extracted methods are private by default, we have to make them non-private, otherwise we have to invoke them by reflection:
Method method = Somecls.class.getMethod("a-private-method");
method.setAccessible(true);
method.invoke(...)
But if we make it non-private, we can just:
Somecls cls = new Somecls();
cls.nonPrivateMethod(...)
If the method is private, then it will be invoked by a public method in that class. Ideally, the test cases should pass through the public method to reach all the possible flows in that private method.
I think this is something pretty personal. In most of the scenarios I don't see any harm on changing the scope of a method from private to protected/package private if this helps to write better unit tests. It not only allows to invoke the method from your test - which you might do either way using reflection -, but also to override/mock that method when testing another one invoking this.
However, if you don't want to do it you still can use tools like Spring's ReflectionTestUtils to make the invocation of private methods less painful.
Yes this is perfectly acceptable for creating unit tests for the private methods. By leaving out the private keyword you create what is a known as a package-private method which can only be accesed by other classes that are in the same package. This lets you create unit test classes in the same package that can call your methods but also provides encapsulation so clients that use your class can't call those methods.

Injected constructors, unit testing and best practices

This is a slightly esoteric questions about how public to make constructors when using an IoC container. I'm using java, Guice and Junit4, but I'm sure this question is more general.
Under Best Practices in the Guice docs, it says "Keep constructors as hidden as possible". This is something I quite agree with, so I was happy to go ahead a make my constructors private and rely on Guice for instantiation.
However, this brings up an issue with mocking classes and unit testing. If all my constructors are private, then how can I instantiate something in a unit test and pass in a mocked dependency? Having to create a new Guice module for every unit test seems like overkill to me. Surely, I must therefore actually make those constructors public.
Which brings me to the question: Given that DI is so useful when combined with unit testing, is the best practices in the Guice docs about keeping constructors hidden actually a mistake?.
Read further in the same document, which suggests giving the constructors default access. Then put your unit tests in the same package.
Default access is provided if none of public, protected or private are specified.
From the document you referenced:
As a correction, simply limit the visibility of both your implementation classes, and their constructors. Typically package private is preferred for both, as this facilitates:
binding the class within a Module in the same package
unit testing the class through means of direct instantiation

Categories