Junit for MessageBoxProvider - java

I have code like below
if (MessageBoxProvider.questionMessageBox(shell, title, message)) {
return performOverwrite(file);
}
I wanted to test(JUnit) how many times performOverwrite(file) method called, I know I can use verify method to test, my problem is MessageBoxProvider.questionMessageBox(shell, title, message) , condition will become only true when user clicks ok, but Using Junits, how can I make if condition true?

Unit testing business logic becomes very complicated if user-interface code is mixed in with it. Ideally, you should adopt a design pattern, such as MVC or MVP that prevents this entirely.
If you can't or won't go down that route, consider defining an interface that contains all your message box methods. E.g.
public interface MessagePrompter {
boolean poseQuestion(title, message);
// ...
}
In your class constructor, accept an object of this type and store it. In your tests, you can mock this object and use it to control what the test user has done.
In your production code, use a concrete implementation of this interface that calls your MessageBoxProvider methods.
This type of approach has the benefit of making your application more portable. If you want to release a command-line version or a web-based version, you simply change the way your concrete implementation behaves.

Related

Unit Test public method that calls private method and other objects in Java

I am new to Unit Testing and recently tried my hands on JUnit test and Mockito.
I am trying to unit test a method that calls multiple private methods and also creates private objects of other classes.
How can I unit test the method.
For Example if I have the following code:
class ClassToTest {
private OuterClass outerClass;
public Boolean function() {
outerClass = new OuterClass(20);
return innerFunction(outerClass.getValue());
}
private Boolean innerFunction(int val) {
if (val % 2 == 0)
return true;
return false;
}
}
I'm confused how would I test the public function.
It doesn't matter how a method is implemented; that method should have a contract it obeys and that is what you are verifying with your test. In this example, function() should return true if the outerClass's value is even. One way to accomplish this would be to inject (pass into the ClassToTest constructor) the instance of outerClass so that you can control the value when testing:
#Test
public void trueWhenEven() {
var outer = new OuterClass(2);
var ctt = new ClassToTest(outer);
assertTrue(ctt.function());
}
Sometimes the contract is just that a method invokes methods on some other objects; in these kinds of cases, you can use Mockito or similar library to verify the interactions.
You are starting unit-testing with directly going at some non-trivial questions.
Question 1: How to handle implementation details / private functions? Answer: Unit-testing is about finding the bugs in your code, and that is one primary goal of unit-testing (and most other kinds of testing). Another primary goal is to prevent the introduction of bugs by acting as regression tests when the software is changed. Bugs are in the implementation - different implementations come with different bugs. Therefore, be sure to test the implementation details. One important tool to support here is coverage analysis, which shows you which parts of the implementation's code have been reached by your tests.
You may even test aspects beyond the contract of the function: a) Negative tests are tests that intentionally check behaviour for invalid / unspecified inputs, and are important to make a system secure. Because, even when provided with invalid input, the system should not allow to be hacked because of, for example, reading or writing out-of-bounds memory. This, however, does probably not apply for your example, because your method most likely is specified to implements a 'total function' rather than a 'partial function'. b) Tests of implementation details (if accessible) can even be performed beyond what is needed by the current implementation. This can be done to prevent bugs in upcoming changes to a component, like, extensions of the API.
There are, however, also secondary goals of unit-testing. One of them is to avoid that your tests break unnecessarily when implementation details change. One approach to also reach the secondary goal is, to test the implementation details via the public API. This way certain kinds of re-design of the implementation details will not break your tests: Renaming, splitting or merging of private functions would not affect the tests. Switching to a different algorithm, however, likely will require you to re-think your tests: Tests for an iterative / recursive implementation of the fibonacci function will look different than for an implementation using the closed-form-expression from Moivre/Binet, or for a lookup-table implementation.
For your example this means, you should try to test the functionality of your private function via the public API.
Question 2: How to deal with dependencies to other parts of the software? Unit-testing focuses on finding the bugs in small, isolated code pieces. When these code pieces have dependencies to other code parts, this can negatively influence your ability to unit-test them properly. But whether this is really the case depends on the actual dependency. For example, if your code uses the Math.sin() function, this is also a dependency to a different code part, but such a dependency does typically not harm your ability to properly test the code.
Dependencies to other components bother you in the following cases: The use of the other components makes it difficult to stimulate all interesting scenarios in your code under test. Or, the use of the other component leads to non-deterministic behaviour (time, randomness, ...). Or, the use of the other components causes unacceptably long build or execution times. Or, the other component is buggy or not even available yet.
If all of these criteria are not met (as it is normally the case with the Math.sin() function), you can typically just live with the other components being part of your tests. You should, however, keep in mind that in your unit-tests you still focus on the bugs in your code and do not start to write tests that actually test the other components: Keep in mind that the other components have tests of their own.
In your example you have chosen Outerclass to have some apparently trivial functionality. In this case you could live with Outerclass just remaining part of your tests. However, it is only an example from your side - The real other class may in fact be disturbing according to the above criteria. If that is the case, then you would somehow have to manage that dependency, which all requires in some way to come to a design that is testing-friendly.
There is a whole family of approaches here, so you better search the web for "design for testability" and "inversion of control". And, you also should try to learn about what distinguishes unit-testing and integration testing: This will help you to avoid trying to apply unit-testing on code parts that should rather be tested with integration testing.
Generally with Mockito this would require the use of Dependency Injection and then you would inject a mock of OuterClass for the test.
If you'd really like to test this without a Spring type framework being added I can think of 3 options:
1) Make this an Integration Test and test the real instances of everything
2) Alter your code so that OuterClass is created via a passed in Object from a setter or a constructor and then pass in a mock for your test
3) Change private OuterClass outerClass; to protected OuterClass outerClass; and make sure your test package structure is the same as your actual code package structure and then you can do outerClass = Mockito.mock(OuterClass); in your test set up.

Java service method only for test

Is there a way to use a service method (a method that is implemented in the service layer (Interface) ) only in test classes?
in my service interface i have a method that i want to use it only in test class
and prevent or show some warning to other developers that doesn't use it in their
managerImpl or other palace such as controller
Lets be precise about wording:
If you are really talking about a method of an Java interface; then Java8 would allow you to provide a default implementation that could throw an exception for example; and then you have very specific classes that implement this interface and maybe override that one method for test purposes.
If you are talking about "interfaces" in general; such as "the list of methods of some class" ... then this kind of "base throws" and "children override" could work as well.
Of course, the first answer might be visibility itself. If we are not talking about a real interface; you could at least make the method package protected; then usage is restricted to the same package.
Another option would be to follow ISP and segregate your interfaces. If there is something that should only be used for "testing"; then consider putting those things into some "TestSupportInterface"; or something alike.
But again; most of these ideas work "by convention"; by providing some sort of information that the user has to digest ... but that can't be enforced.
Finally: you could consider to change your production code. Very often you might not need such "special test getters". In other words: if your tests are working like "fetch state of X. do something with X. fetch state of X again and compare". Sometimes this can be changed to behavior based testing (you don't check what happens to X; but you check what X does to Y, Z, ...).
No, there's no concept in Java to warn developers about using methods.
Rethink if you 'really' need such a method, or if you could change your design to not require such a back door. (e.g. utilize the power of dependency injection). From my experience this is always possible.
If you are still convinced that you want this method implement it in your test code (e.g. by subclassing), not in production code.
It's generally better not to put anything in your production code "only for tests".
You could create a service dedicated to all users suppression and place it in your test classpath.
Depending on your implementation, this service might be a subclass of your production user service.
In addition to the other good answers: If you really need a method to be called by a test case but not by production code, you can make this method private. So unless someone changes the visibility nobody will use this method. And in your test case you can call it via PrivateAccessor.
But be careful: This is mostly considered as code smell. For your IDE this is a private and unused method, so there will be a warning message. And someone else could remove this method because of this.

stubbing private method in Java

I'm testing a function that takes several paramters and on the basis of their values calls different private methods.
I want to check that the function always call the right private method.
Since I know what the private methods will do I can check the final result but it would be more convenient to be able to check directly if the right function was called, because I have already tested the private methods.
Is there a way to replace a privae method with a stub?
Yes, there are mocking libraries that let you do this. One is PowerMock. From their private method tutorial, you need something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyUnit.class)
public class TestMyUnit {
#Test
public void testSomething() {
MyUnit unit = PowerMock.createPartialMock(MyUnit.class, "methodNameToStub");
PowerMock.expectPrivate(unit, "methodNameToStub", param1).andReturn(retVal);
EasyMock.replay(unit);
unit.publicMethod(param1);
EasyMock.verify(unit);
}
}
However, I really disagree with this practice myself. Your unit test should test inputs, outputs, and side effects, and that's it. By ensuring that a private method is called correctly, all you're doing is preventing your code from being easily refactored.
In other words, what if down the road you want to change how your unit does its job? The safe way to do this is to make sure the code is under (passing) tests, then refactor the code (potentially including changing which internal methods are called), and then run the tests again to make sure you didn't break anything. With your approach, this is impossible because your tests test the exact implementation, not the behaviour of the unit itself. Refactoring will almost always break the test, so how much benefit is the test really giving you?
Most often you would want to do this because you're actually considering those privates a unit unto themselves (this sound like you, since you say you are testing those private methods directly already!). If that's the case, it's best to extract that logic into its own class, test it, and then in the remaining code interact with a mock/stub version of that new unit. If you do that, your code has a better structure and you don't need to fall back on the voodoo magic that is PowerMock. A fantastic reference to do these kinds of refactorings is Michael Feathers' Working Effectively with Legacy Code.
You may check java instrumentation to do so
As one of solution can be used proxy from inner classes. You need add inner class inside every your class which must be tested.
But it is not very good solution for big product project. its require create addition script for remove generated classes from your release files(jar/war).
But more easier way will be used PowerMock as wrote in comments bellow(or upper :)) - http://code.google.com/p/powermock/wiki/MockPrivate
Would it be possible to provide the class in question with another object, to which the private methods are moved and made public? In that case, it would be easy to create a test dummy for that interface.
If calling the right "private method" has no observable outside result, are you sure you want to test this? Maybe shouldn't.
If the end result is the same regardless of whether the private method gets called, and you still want to observe its invocation, you could make the method public and move it to its own class, and mock that class. Then you could verify (using Mockito or a similar framework) whether your method is being called.
Code coverage tools do this kind of thing by re-writing the bytecode before the tests are actually run. So, it's got to be possible, but it's non-trivial.
Update: writing a unit test that requires that the "right" private method be called kind of makes the job of refactoring a real pain because then you have to re-write all your tests. That kind of defeats the purpose of the tests.

How to write test cases for complex underlying entity?

I am wriring unit test cases for an existing system. The architecture for the underlying classes if very complex in itself.
Blockquote
RequestHanndler ==> processes ==> Order ===> is dependent on ==> service layer == connected to ==> DB layer.
I am writing a test case for RequestHandler. The method in test(doProcess()) creates a new instance of Order class. Order class itself has very tight dependency on the service layer. I want to create an atomic test case, so, not any other layer of code will be executed.
What should the best process to create test cases for these scenrios?
It might get a bit complicated when you want to write unit-tests for tighly coupled code. To make uni-testing easier you should better rely on abstractions and not on real implementations. E.g. the Order class shouldn't depend on the real implementation of the service layer, instead introduce an interface which is much easier to mock instead of a class which might be set to final.
Since your RequestHandler is responsible for creating the Order instances you'll have to provide a way to mock out the order class in unit-tests. A simply way is to create a protected method that simply creates a new order instance.
protected Order createOrder(String someParam) {
return new Order(someParam);
}
In your Unit-Tests you can now extend the class and overwrite the factory-method.
Using Mockito this would look like:
protected Order createOrder(String someParam) {
Order order = Mockito.mock(Order.class); // create mock object
// configure mock to return someParam when
// String Order#getSomeParam() gets invoked
Mockito.doReturn(someParam).when(order).getSomeParam();
return order;
}
Typical approach for unit testing of such systems is mocking. There are several mockup frameworks for java. I personally used EasyMock but there are others.
So, I think that you should to try to test the logic of request handler first. You should mock Order (i.e. create dummy, not real instance of order using mockup frameork). When this layer is tested go deeper and start testing internal layers.
Other strategy is going from down to up, i.e. test first the internal layers. This strategy is probably "right" but it you will not get fast results that you can show to your manager because managers typically like to see the "big" picture and very seldom go into the details.
Bottom line: good luck.

Junit tests sharing same data object? Should I make a mock of it or what?

I have three classes I need to test, lets say Load, Transform, Perform and they all begin or work on the same data object, at least that's what is required, from one data object X the Load methods perform their thing on it, then it is given to Transform which also does its thing with its methods, and a Perform which changes the data object a bit and it is ready.
Now I want to write tests for Load, Transform and Perform.
The test-data object, should I just make a static method in the Load class like
public static TestData makeTestData(...makeit...)
OR should I make a TestDataMock or TestDataTest class ? Which can return an example of it? And make a new TestDataTest class in each Load, Transform and Perform when they need to work on it?
You should always strive to make unit tests independent of each other. For that reason, you should always create any input test-data fresh for each test, whenever possible. What you want to test is "given input data X, verify that output is Y". JUnit has the #Before annotation which you can use to annotate a method that is to be run before each test-case in that class. Typically, that is where you would put all your set-up code (creating and initilizing mock objects, creating or loading test-data, etc).
Alternativly, you could combine your Load, Transform and Perform actions into one test-case, but that would be more of an integration test than a unit test.
Sounds like a good example where dependencies would be useful, so you don't have to recreate the object every time (or worse, mock it). On top of that, you work with the real output produced by the previous phase, and you don't have to use statics (always a code smell).
JUnit doesn't support dependencies, but TestNG does:
#Test
public void load() { ... }
#Test(dependsOnMethods = "load")
public void transform() { ... }
#Test(dependsOnMethods = "transform")
public void perform() { ... }
If transform() fails, the final report will say "1 Passed (load), 1 Failed (transform) and 1 Skipped (perform)", and you know exactly where to look.
Most test-case classes should be in the style of testcase class per class: if your have a class X it has one corresponding class XTest. But that is not the only way of doing things; if you have a group of classes that cooperate you could use JUnit for some low-level integration testing of the cooperating classes. You need only think of a suitable name for this test-case class.
However, if you have a group of cooperating classes, consider hiding that fact behind a facade, or even just a single method call of some higher-level class. Then treat that facade or high-lelve method as something to unit-test.
Or, are you trying to say that you do not know how to test your three classes in isolation because they are very tightly coupled, and the behaviour of one can not be described without reference to the two others? That suggests you have a poor design: consider a redesign so you can describe the required behaviour of each class in isolation, and therefore test them (at least in part) in isolation.

Categories