I need to add dependencies between behavioural-test methods where I use #RunWith(SpringJUnit4ClassRunner.class) to run the tests.
I add Mockito to the mix by using:
#Rule
public MockitoRule mockitoRule = new MockitoRule();
Where MockitoRule is a short class implementing MethodRule applying Mokito behaviour, I managed to scrounge up somewhere.
Now the question: Anyone have ideas of how I would archive a somthing similar with JExample, ie: applaying it with a #Rule instead of using the #RunWith(JExample.class)?
Looking at Sourceforge and github, it doesn't look like there has been much development in JExample in the last couple of years, so there probably isn't a #Rule for JExample. I would contact the original author to see how easy it would be to add a TestRule.
At first glance, it seems that it would require a slight change to how JExample works, because the return values of the tests are actually used, whereas the base runners for JUnit assume that the methods are void return values.
Related
I am testing a Cordova plugin in Java/Android and I need to initialize my Plugin class and set some state before I run my Tests.
#Before
public void beforeEach() throws Exception {
System.out.println("Creating new Instance ");
PowerMockito.mockStatic(Helpers.class);
PowerMockito.when(Helpers.canUseStorage(any(), any())).thenReturn(true);
MyLogger myLoggerMock = PowerMockito.mock(MyLogger.class);
PowerMockito.doNothing().when(myLoggerMock, "log", anyString());
PowerMockito.whenNew(MyLogger.class).withAnyArguments().thenReturn(myLoggerMock);
this.sut = spy(new FilePicker());
PowerMockito.doNothing().when(this.sut).pick(any(), any());
}
I want to create a Test Suite / Java Class per public function, but I do not want to repeat that code every time.
Is there a way to share that before each between test suites? I have found ClassRule but I think I do not do what I need (or I am understanding it wrong... I am really new in Java)
In Typescript we can share beforeEachfunctions with several suites, and each suite can have their own beforeEach
One possible ways is using inheritance:
Make all test classes extend from one "parent test" class and define a #Before in a parent class.
So it will be called automatically for all the subclasses:
public class ParentTest {
#Before
public void doInitialization() {
....
}
}
public class Test1Class extends ParentClass {
#Test
public void fooTest() {
// doInitialization will be executed before this method
}
#Test
public void barTest() {
// doInitialization will be executed before this method as well
}
}
Two notes:
Note 1
In the code you use sut (subject under test) - this obviously should not be in the parent's doInitialization method, so its possible that Test1Class will also have methods annotated with #Before (read here for information about ordering and so forth)
Then the `sut gets initialized with Spy which is frankly weird IMHO, the Subject Under Test should be a real class that you wrote, but that's beyond the scope of the question, just mentioning it because it can point on mistake.
Note 2
I'm writing it in an an attempt to help because you've said that you're new in Java, this is not strictly related to your question...
While this approach works in general you should be really cautious with PowerMockito. I'm not a PowerMockito expert and try to avoid this type of mocks in my code but in a nutshell the way it manipulates the byte code can clash with other tools. From your code: you can refactor the HelperUtils to be non-static and thus avoid PowerMocking in favor of regular mocking which is faster and much more safe.
As for the Logging - usually you can compromise on it in unit test, if you're using slf4j library you can config it to use "no-op" log for tests, like sending all the logging messages into "nothing", and not-seeing them in the console.
I have this line which is interferring in a unit test:
OtherClass.staticMethodThatWillErrorIfCalled().isAvailable();
If it wasn't static I could just mock OtherClass and then do this:
Mockito.doReturn(null).when(mockedOtherClass).staticMethodThatWillErrorIfCalled();
Mockito.doReturn(true).when(mockedOtherClass).isGuiMode();
and the fact that it will error if called makes my attempts at using powermockito futile.
I'm not sure how I can do this. All I want to do is skip over this line (it's an if check) and continue on as if it had returned true. What is the best way to do this?
I would require more info to give a more specific answer but this is what I am thinking...
First tell PowerMockito that you will be mocking a static method in OtherClass.
#RunWith(PowerMockRunner.class)
#PrepareForTest(OtherClass.class)
These are class level annotations that go on your unit testing class.
Then mock what to do when that method is called.
PowerMockito.mockStatic(OtherClass.class);
Mockito.when(OtherClass.isAvailable()).thenReturn(Boolean.TRUE);
Do this in your #Before method on your unit testing.
This is what I found from my initial attempts to use JMockIt. I must admit that I found the JMockIt documentation very terse for what it provides and hence I might have missed something. Nonetheless, this is what I understood:
Mockito: List a = mock(ArrayList.class) does not stub out all methods
of List.class by default. a.add("foo") is going to do the usual thing
of adding the element to the list.
JMockIt: #Mocked ArrayList<String> a;
It stubs out all the methods of a by default. So, now a.add("foo")
is not going to work.
This seems like a very big limitation to me in JMockIt.
How do I express the fact that I only want you to give me statistics
of add() method and not replace the function implementation itself
What if I just want JMockIt to count the number of times method add()
was called, but leave the implementation of add() as is?
I a unable to express this in JMockIt. However, it seems I can do this
in Mockito using spy()
I really want to be proven wrong here. JMockit claims that it can do everything that
other mocking frameworks do plus a lot more. Does not seem like the case here
#Test
public void shouldPersistRecalculatedArticle()
{
Article articleOne = new Article();
Article articleTwo = new Article();
when(mockCalculator.countNumberOfRelatedArticles(articleOne)).thenReturn(1);
when(mockCalculator.countNumberOfRelatedArticles(articleTwo)).thenReturn(12);
when(mockDatabase.getArticlesFor("Guardian")).thenReturn(asList(articleOne, articleTwo));
articleManager.updateRelatedArticlesCounters("Guardian");
InOrder inOrder = inOrder(mockDatabase, mockCalculator);
inOrder.verify(mockCalculator).countNumberOfRelatedArticles(isA(Article.class));
inOrder.verify(mockDatabase, times(2)).save((Article) notNull());
}
#Test
public void shouldPersistRecalculatedArticle()
{
final Article articleOne = new Article();
final Article articleTwo = new Article();
new Expectations() {{
mockCalculator.countNumberOfRelatedArticles(articleOne); result = 1;
mockCalculator.countNumberOfRelatedArticles(articleTwo); result = 12;
mockDatabase.getArticlesFor("Guardian"); result = asList(articleOne, articleTwo);
}};
articleManager.updateRelatedArticlesCounters("Guardian");
new VerificationsInOrder(2) {{
mockCalculator.countNumberOfRelatedArticles(withInstanceOf(Article.class));
mockDatabase.save((Article) withNotNull());
}};
}
A statement like this
inOrder.verify(mockDatabase, times(2)).save((Article) notNull());
in Mockito, does not have an equivalent in JMockIt as you can see from the example above
new NonStrictExpectations(Foo.class, Bar.class, zooObj)
{
{
// don't call zooObj.method1() here
// Otherwise it will get stubbed out
}
};
new Verifications()
{
{
zooObj.method1(); times = N;
}
};
In fact, all mocking APIs mock or stub out every method in the mocked type, by default. I think you confused mock(type) ("full" mocking) with spy(obj) (partial mocking).
JMockit does all that, with a simple API in every case. It's all described, with examples, in the JMockit Tutorial.
For proof, you can see the sample test suites (there are many more that have been removed from newer releases of the toolkit, but can still be found in the old zip files), or the many JMockit integration tests (over one thousand currently).
The equivalent to Mockito's spy is "dynamic partial mocking" in JMockit. Simply pass the instances you want to partially mock as arguments to the Expectations constructor. If no expectations are recorded, the real code will be executed when the code under test is exercised. BTW, Mockito has a serious problem here (which JMockit doesn't), because it always executes the real code, even when it's called inside when(...) or verify(...); because of this, people have to use doReturn(...).when(...) to avoid surprises on spied objects.
Regarding verification of invocations, the JMockit Verifications API is considerably more capable than any other. For example:
new VerificationsInOrder() {{
// preceding invocations, if any
mockDatabase.save((Article) withNotNull()); times = 2;
// later invocations, if any
}};
Mockito's a much older library than JMockIT, so you could expect that it would have many more features. Have a read through the release list if you want to see some of the less well documented functionality. JMockIT authors have produced a matrix of features in which they missed out every single thing that other frameworks do that they don't, and got several wrong (for instance, Mockito can do strict mocks and ordering).
Mockito was also written to enable unit-level BDD. That generally means that if your tests provide a good example of how to use the code, and if your code is lovely and decoupled and well-designed, then you won't need all the shenanigans that JMockIT provides. One of the hardest things to do in Open Source is say "no" to the many requests that don't help in the long run.
Compare the examples on the front pages of Mockito and JMockIT to see the real difference. It's not about what you test, it's about how well your tests document and describe the behavior of the class.
Declaration of Interest: Szczepan and I were on the same project when he wrote the first draft of Mockito, after seeing some of us roll out our own stub classes rather than use the existing mocking frameworks of the time. So I feel like he wrote it all for me, and am thoroughly biased. Thank you Szczepan.
Without looking into JUnit source itself (my next step) is there an easy way to set the default Runner to be used with every test without having to set #RunWith on every test? We've got a huge pile of unit tests, and I want to be able to add some support across the board without having to change every file.
Ideally I'm hope for something like: -Djunit.runner="com.example.foo".
I don't think this is possible to define globally, but if writing you own main function is an option, you can do something similar through code. You can create a custom RunnerBuilder and pass it to a Suite together with your test classes.
Class<?>[] testClasses = { TestFoo.class, TestBar.class, ... };
RunnerBuilder runnerBuilder = new RunnerBuilder() {
#Override
public Runner runnerForClass(Class<?> testClass) throws Throwable {
return new MyCustomRunner(testClass);
}
};
new JUnitCore().run(new Suite(runnerBuilder, testClasses));
This won't integrate with UI test runners like the one in Eclipse, but for some automated testing scenarios it could be an option.
JUnit doesn’t supporting setting the runner globally. You can hide away the #RunWith in a base class, but this probably won't help in your situation.
Depending on what you want to achieve, you might be able to influence the test behavior globally by using a custom RunListener. Here is how to configure it with the Maven Surefire plugin: http://maven.apache.org/plugins/maven-surefire-plugin/examples/junit.html#Using_custom_listeners_and_reporters
I'm experiencing some difficulties using JUnit 4.5 in Eclipse, when I use #Before annotation it just does nothing (I may use setUp() which works of course, but I'm just wondering what is wrong), while it works perfectly in Netbeans.. Any thoughts?
Because I cam here via a Google Search, and had to dig quite a bit deeper to see the actual solution:
As #Pace said in the comments, if you extend TestCase, Eclipse treats the Test as JUnit Version 3 or older, and does not respect the #Before annotation - also descripred here: JUnit + Maven + Eclipse: Why #BeforeClass does not work?
Hence, removing the extend TestCase causes fixes the problem
If you are using JUnit 4, you can just annotate the test class or the test method with #Test annotation, instead of extending TestCase.
Since you are using JUnit 4+ there are two ways to write a test case
1 > You make your test class extend TestCase. In this case classes corresponding to Junit 3 are picked up which are not aware of #Before annotation. In this case you will have to override
/**
* Sets up the fixture, for example, open a network connection.
* This method is called before a test is executed.
*/
protected void setUp() throws Exception {
}
2 > use annotations. use #Test annotation for the method in the test class that you are interested in running as a test. There is no need for your class to extend TestCase. Also you do not have to override any method. Simply define your own method that has the logic to be executed before the test method runs and annotate it with #Before annotation.