Junit test for nifi processor which extends abstract class - junit

how to write Junit test for nifi processor which extends abstract class
public class myProcessor extends AbstractDatabaseFetchProcessor {
#Override
public void onTrigger(final ProcessContext context, final ProcessSessionFactory sessionFactory)
throws ProcessException {
}
Where the database connection is created from the connection pool DBCPService and some PropertyDescriptors are fetching from the abstract class AbstractDatabaseFetchProcessor.
Im using TestRunner from apache nifi.I would like to mock the database connection and would like to know how to set the controllerService(for connection) as testRunner property.
I'm new to nifi, Can anybody help me?

see the tests for standard processors
DBCPServiceSimpleImpl class
#Before create DBCPServiceSimpleImpl register dbcp service in your runner under some name, enable it, and link processor runner with service by name

Related

Spring-boot Redis JMS JUnit

I am using Redis Server for message broker in my spring boot application.
Is there any simple way to Junit my publish and receive API?
e.g :
Publisher :
public String publish(Object domainObj) {
template.convertAndSend(topic.getTopic(), domainObj.toString());
return "Event Published";
}
Receiver :
public class Receiver implements MessageListener {
#Override
public void onMessage(Message message, byte[] bytes) {
System.out.println("Consumed Message {}" + message);
}
}
I am using JedisConnectionFactory and RedisMessageListenerContainer and RedisTemplate for my implementation
#Configuration
#EnableRedisRepositories
public class RedisConfig {
#Bean
public JedisConnectionFactory connectionFactory() {
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
configuration.setHostName("localhost");
configuration.setPort(6379);
return new JedisConnectionFactory(configuration);
}
#Bean
public RedisTemplate<String, Object> template() {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory());
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new JdkSerializationRedisSerializer());
template.setValueSerializer(new JdkSerializationRedisSerializer());
template.setEnableTransactionSupport(true);
template.afterPropertiesSet();
return template;
}
#Bean
public ChannelTopic topic() {
return new ChannelTopic("common-channel");
}
#Bean
public MessageListenerAdapter messageListenerAdapter() {
return new MessageListenerAdapter(new Receiver());
}
#Bean
public RedisMessageListenerContainer redisMessageListenerContainer() {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory());
container.addMessageListener(messageListenerAdapter(), topic());
return container;
}
Unit Testing Receiver and Publisher implementation is quite straight.
JUnit 5 coupled with Mockito extension should do the job.
For example for testing that :
public String publish(Object domainObj) {
template.convertAndSend(topic.getTopic(), domainObj.toString());
return "Event Published";
}
I expect that topic and template be fields of the current class.
These fields could be set by constructor.
So you could write something that check that convertAndSend() is eventually executed with the correct parameters :
#Mock
RedisTemplate<String, Object> templateMock;
#Test
void publish(){
Topic topicFixture = new Topic(...);
Object domainObjFixture = new FooBar(...);
Publisher publisher = new Publisher(templateMock, topicFixture);
//when
publisher.publish(domainObjFixture);
// then
Mockito.verify(templateMock)
.convertAndSend(topicFixture.getTopic(), domainObjFixture);
}
But I don't think that the unit test of these two classes be enough because it never tests the final things : the JMS processing performed by Redis backend.
Particularly, the RedisConfig part that you set with specific things as serializers that have important side effects on the processing.
For my part, I try to always write integration or partial integration tests for Redis backend stuffs to ensure a good no regression harness.
The java embedded-redis library is good for that. It allows to start a redis server
on localhost (works on Windows as well as on Linux).
Starting and stopping the redis server is as simple as :
RedisServer redisServer = new RedisServer(6379);
redisServer.start();
// do some work
redisServer.stop();
Move the start() in the #BeforeEach and the stop() in the #AfterEach and the server is ready.
Then it still requires some adjustments to ensure that the redis configuration specified in Spring is well setup during the tests while using your local redis server and not the "real" redis server. Not always simple to set but great when it is done !
The simplest way to unit test this is to use embedded-redis module. What you do is in BeforeAll you can start embedded Redis and stop the embedded Redis in AfterAll method.
You can also PostConstruct PreDestroy annotations to accomplish this.
If you're looking for Junit5 then you can find the code in my repo here
See BootstrapRedis annotation and their usage here
https://github.com/sonus21/rqueue/blob/7ef545c15985ef91ba719f070f7cc80745525047/rqueue-core/src/test/java/com/github/sonus21/rqueue/core/RedisScriptFactoryTest.java#L40

Unable to Mock functions inside static method Powermock

I am writing unit test for the below code using junit and mockito
public class Abc implements Runnable
{
private static ServerSocket server;
private static int port;
public Abc(int cPort)
{
port = cPort;
}
public void run()
{
init();
}
public static void init()
{
try {
server = new ServerSocket(port);
...something...
client.close();
}
}
catch(IOException e)
{
System.out.println("Exception inside init()...");
e.printStackTrace();
}
}
};
Unit test I have written
#RunWith(PowerMockRunner.class)
#PrepareForTest({ServerSocket.class})
public class abcTest {
#Mock (name = "server") //same name as private var.
ServerSocket mockServer;
#InjectMocks
Abc abc;
#Test
public void testInit() throws Exception {
int port = 1880;
Socket mockClient = Mockito.mock(Socket.class);
PowerMockito.whenNew(ServerSocket.class).
withArguments(anyInt()).thenReturn(mockServer);
abc = new Abc(port);
Abc.init();
PowerMockito.verifyNew(ServerSocket.class).withArguments(port);
}
};
But the call always go to original function definition. I am using junit 4.11 with mockito 2.28.2 and powermockito 2.0.2. I'm using java after a long time. Now its feel like kind of new. Please correct me if anything wrong in the code also.
You will need to change your PrepareForTest annotation
to #PrepareForTest({Abc.class}).
From the PowerMockito docu:
This annotation tells PowerMock to prepare certain classes for testing. Classes needed to be defined using this annotation are typically those that needs to be byte-code manipulated
In this case that refers to the class which creates the new instance of ServerSocket. ServerSocket itself is a non-final public class that does not require special handling from PowerMockito (instead Mockito can deal with this class on its own).
You could also change your test to do the following:
#Test
public void testInit() throws Exception {
int port = 1880;
ServerSocket mockServer = Mockito.mock(ServerSocket.class);
PowerMockito.whenNew(ServerSocket.class)
.withArguments(Mockito.anyInt()).thenReturn(mockServer);
Abc.port = port;
Abc.init();
PowerMockito.verifyNew(ServerSocket.class).withArguments(port);
}
(This first point is unrelated to whether the test fails or succeeds)
I do not know why you mix object's and static method behaviour together, but I think you should change that.In the test instead of creatic an ABC object, just could just set the static port variable directly.
Or alternatively change the whole ABC class into an object.
#InjectMocks failed for me as there is no default constructor
(Actually I got an error message in the console when trying to execute your code)
Additonaly you create a new instance of ABC in your test, which would have overwritten the things done by the annotations. Also as server is created during the init call, there is no need to inject a mock for it.
powermockito 2.0.2 actually depends on junit 4.12, so I am not sure what effects downgrading to an older version might have.
Socket mockClient seemed somewhat unrelated to the code your posted, so I removed it from my example in the answer, however as you use a client (I assume that is your Socket) in your code your probably need to do some mocking for that as well and provide the mock to the method accordingly.

How to write Junit for a service component class using webtestclient in Spring 5

I'm using Springboot2, Spring5 and reactive-webflux in my Java microservices.
I have a service class which I want to test using webtestclient:-
#Service("authenticationProvider")
public class CommonAuthenticationProvider implements AuthenticationProvider {
#Override
public AccessToken getUserAccessToken(Tuple2<String, WebClient> serviceConnectionDetails, MultiValueMap<String, String> queryParams) {
return serviceConnectionDetails._2
.post()
.uri(builder -> builder
.path(serviceConnectionDetails._1)
.queryParams(queryParams)
.build())
.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
.retrieve()
.bodyToMono(AccessToken.class)
.block();
}
}
Here serviceConnectionDetails._2 is a webclient instance. I want to write a JUnit test to mock this webclient and test the method getUserAccessToken(). Please assist as I had tried many things like mockmvc, mockRestServiceServer but nothing worked. Later I came to know that, I cannot user mockRestServiceServer since it used to mock RestTemplate and not WebClient. I can test controller class methods using webtestclient but not this at service class
This should be supported in a future Spring Framework version with MockRestServiceServer; see SPR-15286.
For now, the only solution is to use a separate library for that, such as okhttp's MockWebServer.

How to execute some code after Cucumber report is built?

I use Cucumber for jUnit runner to run BDD tests like this:
#RunWith(Cucumber.class)
#CucumberOptions(
format = {"pretty", "json:target/cucumber.json"},
glue = {"com.company.bdd.steps"},
features = {"classpath:bdd-scenarios"},
tags = {"~#skip"}
)
public class CucumberTests {
}
I would like to have beautiful HTML reports from https://github.com/damianszczepanik/cucumber-reporting
And i made jUnit #AfterClass method:
#AfterClass
public static void buildReport() throws Exception {
List<String> srcReportJson = Collections.singletonList("target/cucumber.json");
Configuration configuration = new Configuration(new File("target"), "AEOS BDD Integration Tests");
new ReportBuilder(srcReportJson, configuration).generateReports();
}
The problem is that cucumber.json is empty when #AfterClass method executes. Hence i can't build pretty HTML report.
Is there any hook which i can use to execute some code after cucumber json report is already built?
PS: Cucumber v.1.1.8 is used and Java 1.7 so i was not able to try ExtendedCucumberRunner
Have you considered adding shutdown hook? Here is an example on how to add one. Code in run() method supposed to be executed before JVM shuts down.
You can take a look at custom formatter of cucumber:
Thank you for your suggestions but I just decided to use already existing Maven plugin and execute it's goal right after test goal.
wjpowell posted this suggestion in the cucumber-jvm issues:
"You don't need to do this in cucumber. Use the #beforeclass and #afterclass annotation from within the JUnit test used to run the cucumber tests. This has the benefit of running only for the features specified by the paths or tags options.
#RunWith(Cucumber.class)
#Cucumber.Options(format = {"html:target/cucumber-html-report", "json-pretty:target/cucumber-json-report.json"})
public class RunCukesTest {
#BeforeClass
public static void setup() {
System.out.println("Ran the before");
}
#AfterClass
public static void teardown() {
System.out.println("Ran the after");
}
}
"

Selenium 2 - How to run multiple JUnit tests with one WebDriver Instance in Java?

my TestCases (TestClasses) like TestLogIn, TestLogOut, TestSendEmail, TestDeleteEmail etc are starting everytime new ChromeDriver instance .. How can I run multiple tests with one WebDriver instance? Can anyone provide me some example?
My structure in java:
GenericClass.java:
public class GenericClass extends TestCase
//some code
TestLogin.java:
public class TestLogin extends GenericClass
//code
My idea for solving this was to make the WebDriver static.
public class ProjectTests {
static WebDriver driver;
#BeforeClass
public static void setStuff()
{
driver = new FirefoxDriver();
}
#Test
public void testOne(){}
Then, you can pass the driver instance to each of the test methods. The tests will be performed in the same instance of the WebDriver.
Maybe it's not the most elegant method of doing it, but for me it works.