How do frameworks like Spock or Mockito work? - junit

What is the mechanism that frameworks like Spock or Mockito work.
You can mock a method call . You can mock a whole class.
But how is that possible ??
It means you must be able to manipulate the normal execution of code.

Related

Can we now mock static methods with Mockito 2?

I read that Mockito 2 doesn't use CGLIB/proxy any more but instead uses ByteBuddy for mock creation. Does that mean that from now on it is possible to mock static methods and private methods?
No, you can't (see their documentation here; I am sure they would mention that).
So, PowerMock(ito) and JMockit are the two mocking frameworks that support mocking static methods.
But, some personal opinion: one should nonetheless prefer to use Mockito instead PowerMock(ito); simply by writing code that can be tested with Mockito; and that doesn't need PowerMock. What I mean is: when you write your own code and you think you need to mock static calls; then you are writing hard to test code.
The answer is not to look to powerful mocking frameworks; but to write easy to test code instead. You can have a look into these videos to learn how to do that.
Finally: don't think that PowerMockito is a good alternative. Mockito is right now at version 2.79 (as of March 2017). But when you have a look at PowerMockito; you will find that it ships with some Mockito 2.0.42 beta something - because the PowerMockito folks can't get their tool working with any newer version of Mockito. And that is a shame, because those newer Mockito versions have a lot of interesting features.
I wrote an extension of Mockito 2 which uses AspectJ to allow mocking even things like static/private/final methods, with one easy lambda-based syntax, for example:
when(() -> YourClass.staticMethodToCall(...)).thenReturn(...)

Mockito equivalent of EasyMockRule?

I find very little reason to use EasyMock, with Mockito available.
However, when I have a class with a million dependencies, I prefer annotation syntax - Mockito #Mock/#InjectMocks or EasyMock #Mock/#TestSubject.
As far as I can tell from poking around, with Mockito I have to use MockitoJUnitRunner, or MockitoAnnotations.
MockitoJUnitRunner supports field injection, but as far as I can see, the latter requires constructor/setter injection. When I need to use a different runner, and don't want to add constructors or setters to my production code for testing, I seem to be stuck with EasyMockRule.
Does Mockito provide an equivalent, to allow non-Mockito runners and field injection?
Thank you
You can use org.mockito.junit.MockitoJunit.rule().
#Rule
public final MethodRule mockito = MockitoJunit.rule();

JUnit equivalents for TestNG's #BeforeSuite, #BeforeTest

I'm refactoring some test classes from TestNG to JUnit 4. During the process, I've stumbled upon the following annotations:
#BeforeTest
#AfterTest
According to the manual:
The annotated method will be run before/after any test method belonging to the classes inside the tag is run.
What would be the equivalent annotations in JUnit?
This is the original answer, but I think it is wrong. See below for a better one
The equivalent would be the annotations
#Before
and
#After
see also http://junit.sourceforge.net/javadoc/org/junit/Before.html
This is a better answer, after I learned about the difference between Before/AfterMethod and Before/AfterTest in TestNG
If I got it right, with Before/AfterTest you can run a method before or after a list of tests, that you specify inside the annotation or a separate document.
There is no out of the box feature like this in JUnit.
Probably the best you can do, is put what ever you want to do in a JUnit Rule. See also http://schauderhaft.de/2011/07/24/rules-in-junit-4-9-beta-3/
Then you can use that Rule in any test that needs it.

Extending Junit4 or test case?

We've got a simple webservice for handling queries about our data. I'd like to make a set of asserts/case extentions that would provide high level methods for testing various aspects of the response. For instance I could write assertResultCountMinimum(int). The method would take care of building the query, executing it, and unpacking the response to validate the data. I'd also like the to
I want to make sure I have the right idea in my head about how to go about this.
First create a test case class of my own, with the right setup and teardown methods. For our purposes, MyTestCase. Then provide a series of classes that extend Assert with the new assert methods. The end user of these classes would extend MyTestCase and would use the asserts that I've created. This is the pattern I think I see in jWebUnit.
I feel like I'm mixing and matching junit 3 and 4 concepts. I'd love to have just junit 4 concepts. But I can't seem to line up in my head the proper way to build this. Also, the assert methods that belong to Junit's Assert class are all static. Some of my asserts would require requerying the webservice. This makes me think I should really just provide the asserts as a series of helper functions inside of MytestCase. The later gets the job done, but doesn't feel right.
Any insight, musings, requests for clarification, much appreciated.
Follow up edit:
As Jeanne suggests below, I'm creating a super class with all of my asserts & setup/teardown methods. In reality my asserts are actually helper functions which wrap around the basic junit 4 asserts, which I import into my super class. Any test of mine will just extend this super class. One caveat that I'm considering is making the super class abstract, since there shouldn't be any instance of the super class.
Marc,
I use two patterns in JUnit 4. For "utility type" assertions, I made a static class. For example ReflectionAssertions. Then I use a static import to use those assertions in my JUnit 4 test.
For local type assertions that are only used in one class, I make them regular methods in the JUnit 4 test class itself. For example assertCallingMyBusinessMethodWithNullBlowsUp(). These don't have much reuse value.
I don't consider this mixing concepts because the later group aren't reusable outside my test. If I had reusable assertions that made webservice calls (and therefore needed state), I would create a superclass that did not extend TestCase and use that. My superclass would have the state and #Before methods for setup. As such, it is part of the test.

How do I define a TestSuite without using #SuiteClasses in Junit 4.5?

I'm trying to migrate to JUnit 4 and I'm not clear about the correct way to set up test suites.
I know how to set up a test suite with fixed tests using the #SuitesClasses annotation.
However, I want to have a top-level suite class, where I can programatically decide which test classes or suites I want to load. I know that there are addTest and addTestSuite operations in the TestSuite class.
However, if I define a TestSuite subclass with a constructor that attempts to add these tests and try to run it, I get an error "Must have SuiteClasses annotation".
Any idea how to do this?
I would recommend creating a subclass of the BlockJUnit4ClassRunner and pull in the classes you want to test manually. The protected methods of the class do all the hard work for you, although you might want to tweak the Descriptions a bit to make sure the results are all unique in the output files.