#Rule annotation is not considered in spock unit tests using Junit5 - java

I'm trying to migrate my project to use Junit5. So far I've been using a class "LogSpy" that basically intercepts and saves all the logs so they can be tested easily. Using Junit4 and Spock test I was able to initialize my log interceptor class by using the #Rule annotation (even though it is in a Spock test). After migrating to Junit5 this annotation doesn't seem to initialize the needed log interceptor class and I can't find the reason why. Why did this happen? What are the differences between Junit4 and 5 regarding the #Rule annotation? Is there a way around this issue?
This is how I initialize the LogSpy class. It initializes in JUnit unit tests but not in Spock tests.
#Rule
public LogSpy logSpy = new LogSpy()

From the release notes
JUnit 4 Rules are not supported by spock-core anymore, however, there is a new spock-junit4 module that provides best effort support to ease migration.
In short add the spock-junit4 dependency, if you still need to use JUnit 4 rules.
In the long term, I would suggest to migrate to Spock native extensions.

Related

Why adding #RunWith annotation to my JUnit tests if they work as expected without it?

I always add the #SpringBootTest to my test classes when using Spring Boot and my tests work as expected. I wonder what benefit do I get from also adding #RunWith(SpringRunner.class), since all over the internet that annotation is being used.
The #RunWith(SpringRunner.class) provides support for loading ApplicationContext and having beans #Autowired into your test instance.

Running JUnit with both Spring and Parameterized

I have certain integration tests that require the Spring context and will benefit greatly from parameterized testing (will remove lots of duplicate code). I currently have the test running with the class annotation
#RunWith(Parameterized.class)
and I load up the Spring context with
#ClassRule
public static final SpringClassRule SPRING_CLASS_RULE = new SpringClassRule();
#Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
The above works, but to be frank, I have no clue what it's actually doing. Can anyone explain, and are there any other ways to run parameterized tests simultaneously with Spring?
Any IDE will allow you to jump to the definitions of the SPring rules and debug them. Same for the JUnit Parametrized class.
A JUnit Rule does preparation before and after each method, and before and each after class.
A JUnit Runner does preparation before and after each method, and before and each after class, then runs all methods
Both Spring test rules do the same preparation / cleanup as the Spring Runner would do.
As you can see, rule and runners do mostly the same, the only reason there is a Spring runner is for convenience.
Other ways to run this reasonably would be using JUnit5 or TestNG maybe, instead of JUnit4. Or probably there is a way to setup all spring context in an #Before method rather than using annotations.
But really what you have been doing is the recommended way to combine Spring setup with parametrized tests.

Mocking Local Scope Objects using mockito or any other framework without compromising junit coverage

Here is my problem statement with example,
void method1() {
A a = new A();
a.dosStuff();
}
I want to mock a.dosStuff() in my test using Mockito or any other framework.
I have tried with powermock it helped me out but problem is that it is not showing JUnit coverage in tools like Sonar and EclEmma.
So, is there any way to do this in Mockito or any other framework without compromising JUnit coverage?

Why ExpectedException is deprecated in Spring

On the one side, there is a new #RunWith annotation that lets to change unit test framework on the fly.
But on the other side Spring documentations says about org.springframework.test.annotation.ExpectedException:
#deprecated as of Spring 3.1 in favor of using built-in support for declaring expected exceptions in the underlying testing framework (e.g., JUnit, TestNG, etc.)
As a result my code will depend on the unit test framework. Please explain it.
And the 2nd question. At the moment I implement tests with Spring #RunWith annotation. But I also add the jUnit specific org.junit.Test annotation to each test method. Again, if I understand correctly the best way - to write tests, so I could change for example jUnit onto TestNg. And Spring #RunWith helps me to do that. But how can I avoid using of the org.junit.Test annotation?
#RunWith isn't a Spring annotation. It's a JUnit one. It doesn't let you switch between JUnit and TestNG, as you seem to think. Instead, it lets you run JUnit tests in different ways, like with the addition of the Spring Test Framework. In that framework, Spring has provided ExpectedException for some time, but it's no longer needed because recent versions of both JUnit and TestNG provide that functionality now.
You cannot write a test which can run on both JUnit and TestNG, so your code is bound to be dependent on testing framework. #RunWith is not a Spring's annotation for running tests with different testing frameworks, it belongs to JUnit and used to run JUnit with other runners like SpringJUnit4Runner to extend JUnit functionality

testNG tests extending BaseTest

We noticed that when testNG test cases extend TestCase (JUnit) those tests start executing as Junit tests. Also, I should probably mention, the tests are run through Maven.
Is this a bug or a feature? Is it possible to override this behavior and still run those types of tests as TestNG tests? Do you know a link where TestNG talks about this?
thanks.
I didn't think either TestNG or JUnit required any base classes now that both use annotations to specify test methods. Why do you think you need to extend a class? And why on earth would a TestNG class extend the JUnit base class TestCase? Is it any surprise that they run as JUnit tests?
It sounds like neither bug nor feature but user error on your part. I'm not sure what you're getting at here. Why would you do this?
UPDATE: Your question is confusing me. Did you have JUnit tests running successfully that you're not trying to convert to TestNG, or visa versa? I'm having a very hard time understanding what you're trying to achieve here. Leave Maven out of it. It's immaterial whether they're run by you, Ant, or Maven.
Looking at the maven surefire plugin info I can't see any way to select a test for TestNG processing only if it also extends a jUnit 3 class.
IFAIK your best bet is to just work on each class seperately, removing the jUnit references and then retesting. That way you never have the mixture in one class and you should avoid problems. To make the work manageable I would be inclined to do this only when I was changing a test case for some other reason.

Categories

Resources