I am using jmockit to mock my classes for unit test purpose. Everything is working fine so far.
I have a factory which is thread safe and singleton as shown below:
So for below class, I am able to get 50% Line Coverage because I am not able to cover private constructor TestFactory().
public class TestFactory {
// not able to cover this
private TestFactory() {}
private static class TestHolder {
private static final TestClient INSTANCE = new TestClient();
}
public static IClient getInstance() {
return TestHolder.INSTANCE;
}
}
My question is - Is there any way I can cover TestFactory() private constructor so that I can get 100% Line Coverage in my Cobertura Report for this class?
Invoke it using reflection or just mockit.Deencapsulation.newInstance(). Write a test method like this
#Test
public void privateConstructorCoverage() throws Exception {
Deencapsulation.newInstance(TestFactory.class);
}
Deencapsulation javadoc
Provides utility methods that enable access to (ie "de-encapsulate") otherwise non-accessible fields, methods and constructors belonging to code under test.
Related
I have a scenario where I call a static function from another function. How can we write unit tests in such cases?
Here is my code:
public class TradesHelper {
public static double calculatePL(Market market, Trade trade) {
double pl = (Helper.priceDifference(market, trade) / market.getSize()) * trade.getQuantity() * Helper.effectiveValue(market);
return pl;
}
}
public class Helper {
public static priceDifference(Market market, Trade trade) {
//Do something here
}
}
This is how I am trying to write unit test case:
I have written a unit test case for Helper class. But for TradesHelper class this is how I am trying to write:
public class TradesHelperTest {
#Mock
Market market;
#Mock
Trade trade;
#Test
public void calculatePlFromPips_Test() {
//Trying to return a value when priceDifference function in Helper class is called
Helper helper1 = spy(new Helper());
doReturn(0.0012999999999999678).when(helper1).priceDifference(new Market(),new Trade());
}
But I am getting thus error:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, which is not supported
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
I am new to writing unit tests. Can someone guide me on how to do it write?
Thanks
As the comments tell you cannot mock static methods with pure "vanilla" Mockito.
But static access is a bad design and should be avoided. You problem creating a test is the prove that static access makes the code using tightly coupled and therefor hard to reuse (since testing is kind of "reuse"...).
Static access also effectively prohibits inheritance and polymorphism, two major concepts why we are using an OO language.
On the other hand there is not rule that "helper classes" or "utility classes" (in the sense that they provide common behavior) must have static methods. This is only a misconception because classes with only static methods used to be called "utility classes".
So instead of surrendering to your bad design and using Powermock you should change both class Helper and class TradesHelper to have non static methods and use objects of them in your production code.
Java is an object oriented programming language after all, so why avoiding objects?
But do not instantiate Helper inside TradesHelper. Pass the instance of Helper in as a constructor parameter:
public class TradesHelper {
private final Helper helper;
public TradesHelper(Helper helper){
this.helper = helper;
}
public double calculatePL(Market market, Trade trade) {
// ...
public class TradesHelperTest {
#Mock
Market market;
#Mock
Trade trade;
#Mock
private Helper helper;
private TradesHelper tradesHelper; // class under test, no mock nor spy!
#Before
public void setup(){
tradesHelper= new TradeHelper(helper);
}
#Test
public void calculatePlFromPips_Test() {
// arrange
doReturn(0.0012999999999999678)
.when(helper)
.priceDifference(market,trade);// use mocks here not new objects
// act
tradesHelper.calculatePL(market,trade);
// assert
// either assertThat() or verify()
}
}
I'm trying to mock the following class which contains some static members
public class ClientFact {
private static final String BASE_URL = Config.getProperty("prop1");
private static final String USERID = Config.getProperty("prop2");
......................
public static Client createClient() throws AppException {
}
}
but i'm running into issues with the static member variables which are populated by Config.getProperty. This class does a read on a properties file like so
public class Config {
...............
public static String getProperty(Param param) {
String value = null;
if (param != null) {
value = properties.getProperty(param.toString());
}
return value;
}
}
I'm trying to mock this call since i dont care about the loaded properties in my test. This is what ive tried
#RunWith(PowerMockRunner.class)
#PrepareForTest({ClientFact.class})
public class MyTests {
#Test
public void test() {
PowerMock.mockStaticPartial(Config.class, "getProperty");
EasyMock.expect(Config.getProperty(EasyMock.anyObject())).andReturn(EasyMock.anyString()).anyTimes();
PowerMock.mockStatic(ClientFact.class);
}
}
but its giving the following error...
java.lang.NoSuchMethodError: org/easymock/internal/MocksControl.createMock(Ljava/lang/Class;[Ljava/lang/reflect/Method;)Ljava/lang/Object;
at org.powermock.api.easymock.PowerMock.doCreateMock(PowerMock.java:2214)
at org.powermock.api.easymock.PowerMock.doMock(PowerMock.java:2163)
any ideas what im doign wrong here?
A non-answer: consider not making static calls there.
You see, that directly couples that one class to the implementation of that static method in some other class; for no real reason. (and for the record: it seems strange that a USER_ID String is a static field in your ClientFact class. Do you really intend that all ClientFacts are using the same USER_ID?!)
You could replace that static call with a non-static version (for example by introducing an interface); and then you can use dependency injection to make an instance of that interface available to your class under test. And then all your testing works without the need to Powermock.
Long story short: very often (but not always!) the need to turn to Powermock originates in production code which wasn't written to be testable (like in your case). Thus instead of using the big bad Powermock hammer to "fix" your testing problem, you should consider improving your production code.
You might want to listen to those videos to get a better understanding what I am talking about.
I've been writing a lot of JUnit tests lately and see this same boilerplate pattern.
public class MathOpTest {
private MathOp a;
#Before
public void setUp(){
a = new MathOp();
}
...
}
Is there an annotation to set this up for me as I always need to write a setUp method and it usually only has the single class I'm testing.
Something like:
public class MathOpTest {
#TestSubject
private MathOp a;
...
}
You can assign the fields when they are declared:
public class MathOpTest {
private final MathOp mathOp = new MathOp();
...
}
This is simple and straight-forward, so I recommend that you assign fields in your test class at declaration time whenever possible (certainly in the case you gave).
If you want to understand a bit more, read on.
JUnit will create a unique instance of your test class for each test method, so even if your test modifies internal state of MathOp, using fields this way is safe as long as your tests don't modify global state.
For JUnit4-style tests (i.e. tests that do not extend junit.framework.TestCase) JUnit will create the test class just before the test method is run, and make it eligible for garbage collection after the test method completes.
Use #Before methods for more complex initialization.
Usually I use #Before when:
Initialization of the field is complex
Initialization of the field requires calling code that is declared to throw a checked exception
You need to do initialization after a #Rule has been applied (for instance, injecting a mock into a constructor)
Usually you would create the object under test in the test method when the class needs to be constructed different ways for different use cases.
Examples
Here is an example of using #Before and initMocks():
public class MathOpTest {
#Mock private Calculator mockCalculator;
#Mock private Supplier<Double> mockPreviousResultSupplier;
private MathOp mathOp;
#Before
public void createMathOp() {
MockitoAnnotations.initMocks(this);
mathOp = new MathOp(
mockCalculator, mockPreviousResultSupplier);
}
...
}
Here's an example of a #Before method that uses the result of a #Rule:
public class MyWriterTest {
#Rule public final TemporaryFolder folder = new TemporaryFolder();
private File output;
private MyWriter writer;
#Before
public void createMyWriter() {
output = folder.newFile();
writer = new MyWriter(output);
}
...
}
Aside: I personally wouldn't recommend using #InjectMocks to create the class you are testing. It's too much magic for my taste. Having an explicit constructor is cleaner and simpler, and I like my tests to be clear and simple :-)
Nothing like this directly exists in vanilla JUnit to my recollection. Most people elect to either initialize their test subject in a #Before statement, or inside of their tests. In its defense, it makes it clear what is being established before the tests are run, and it always resets the state of your test object.
If you're using Mockito, you actually do have the benefits of declaring a class and annotating it with #InjectMocks to both instantiate the class and inject whatever #Mock classes you had prior.
Is there a way to invoke a private static method of an enumerated singleton? For example, say I have some legacy code that I need to test which has the following structure:
public enum Singleton {
INSTANCE;
private static double methodToTest() {
return 1.0;
}
public static String extremelyComplexMethod() {
methodToTest();
//Imagine lots more complex code here
return "";
}
}
How would I go about creating a class that tests methodToTest in isolation? I've tried reflection using Whitebox (included in PowerMock) but I've had no luck. Is there a way to do it?
I know that testing a private method directly is not the prefered method of doing things, but I want to know if its possible to test the private method directly. I tried to get the code to get recognized as java, but I was unsuccessful.
I was able to invoke the method try this following code
#RunWith(PowerMockRunner.class)
#PrepareForTest(Singleton.class)
public class MySingletonTest {
#Test
public void test() throws Exception{
Whitebox.invokeMethod(Singleton.class, "methodToTest");
}
}
Don't forget to add the Singleton class in PrepareForTest
I have a class FileGenerator, and I'm writing a test for the generateFile() method that should do the following:
1) it should call the static method getBlockImpl(FileTypeEnum) on BlockAbstractFactory
2) it should populate variable blockList from the subclass method getBlocks()
3) it should call a static method createFile from a final helper class FileHelper passing a String parameter
4) it should call the run method of each BlockController in the blockList
So far, I have this empty method:
public class FileGenerator {
// private fields with Getters and Setters
public void generateBlocks() {
}
}
I am using JUnit, Mockito to mock objects and I've tried using PowerMockito to mock static and final classes (which Mockito doesn't do).
My problem is: my first test (calling method getBlockList() from BlockAbstractFactory) is passing, even though there is no implementation in generateBlocks(). I have implemented the static method in BlockAbstractFactory (returning null, so far), to avoid Eclipse syntax errors.
How can I test if the static method is called within fileGerator.generateBlocks()?
Here's my Test Class, so far:
#RunWith(PowerMockRunner.class)
public class testFileGenerator {
FileGenerator fileGenerator = new FileGenerator();
#Test
public void shouldCallGetBlockList() {
fileGenerator.setFileType(FileTypeEnum.SPED_FISCAL);
fileGenerator.generateBlocks();
PowerMockito.mockStatic(BlockAbstractFactory.class);
PowerMockito.verifyStatic();
BlockAbstractFactory.getBlockImpl(fileGenerator.getFileType());
}
}
I have no experience with PowerMock, but since you didn't get an answer yet I'm just been reading through the documentation to see if I can help you a bit on your way.
I found that you need to prepare PowerMock so that I knows which static methods it needs to prepare to be mocked. Like so:
#RunWith(PowerMockRunner.class)
#PrepareForTest(BlockAbstractFactory.class) // <<=== Like that
public class testFileGenerator {
// rest of you class
}
Here you can find more information.
Does that help?
Working example:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ClassStaticA.class, ClassStaticB.class})
public class ClassStaticMethodsTest {
#Test
public void testMockStaticMethod() {
PowerMock.mockStatic(ClassStaticA.class);
EasyMock.expect(ClassStaticA.getMessageStaticMethod()).andReturn("mocked message");
PowerMock.replay(ClassStaticA.class);
assertEquals("mocked message", ClassStaticA.getMessageStaticMethod());
}