RPC is block while used in unit test - unit-testing

I want to test wheter gRPC works, so i start the server in junit test with a thread(see setUp in below code). Everything is ok in non-unit test.
But when I use client to connect the server, it blocks.
#Before
public void setUp() throws InterruptedException {
rpcSever = new RPCServerImpl();
new Thread(rpcSever).start();
TimeUnit.SECONDS.sleep(10);
rpcClient = new RPCClient("localhost", 50051);
}
//#Test
public void testPing() throws InterruptedException {
assertTrue(rpcClient.ping());
}

You can reference https://github.com/grpc/grpc-java/tree/master/examples/src/test/java/io/grpc/examples/helloworld for how to test grpc.

Related

Spring boot mocking static methods with PowerMock in Integration test

I'm writing integration test on a RestController in SpringBoot.
Normally I would run with SpringRunner.class, but when it comes to Mock a static method I need to use PowerMock.
The strange fact is that when I run the single tests, they individually pass (but returns error messages), when I try to run the entire test class, no test passes and it returns the same error message.
#RunWith(PowerMockRunner.class)
#PrepareForTest({JwtUtils.class})
//#PowerMockRunnerDelegate(SpringRunner.class) THIS DOESN'T WORK!!!
#SpringBootTest(classes = SpringBootJwtApplication.class)
public class RestAccessIntegrationTest {
#Autowired #InjectMocks
RestController restController;
#Mock
HttpServletRequest request;
#Test
public void operationsPerAccountWhenSuccessfulTest(){
mockStatic(JwtUtils.class);
when(JwtUtils.myMethod(request)).thenReturn("blabla");
String expected = ... ;
String actual = restController.getOperations();
assertEquals(actual, expected);
}
}
If I run the test or the entire class I get an error of this type:
Exception in thread "main" java.lang.NoSuchMethodError: org.powermock.core.MockRepository.addAfterMethodRunner(Ljava/lang/Runnable;)at org.powermock.api.mockito.internal.mockcreation.MockCreator.mock(MockCreator.java:50)
If I uncomment #PowerMockRunnerDelegate(SpringRunner.class) there it comes this other error:
Exception in thread "main" java.lang.NoClassDefFoundError: org/powermock/core/testlisteners/GlobalNotificationBuildSupport$Callback
at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.run(DelegatingPowerMockRunner.java:139)
In the when method, try using any(HttpServletRequest.class) instead of the request mock object. Also use MockHttpServletRequest instead of mocking HttpServletRequest. This should work,
#RunWith(PowerMockRunner.class)
#PrepareForTest(JwtUtils.class)
#PowerMockIgnore( {"javax.management.*"})
public class RestAccessIntegrationTest {
#InjectMocks
private RestController restController;
private MockHttpServletRequest request;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
request = new MockHttpServletRequest();
RequestContextHolder.setRequestAttributes(
new ServletRequestAttributes(request));
}
#Test
public void operationsPerAccountWhenSuccessfulTest() {
mockStatic(JwtUtils.class);
when(JwtUtils.myMethod(any(HttpServletRequest.class)))
.thenReturn("blabla");
String expected = ... ;
// does your getOperations take HttpServletRequest
// as parameter, then controller.getOperations(request);
String actual = restController.getOperations();
assertEquals(actual, expected);
}
}
It was due to incompatibility in library version of PowerMock and Mockito. I suggest to check the compatibility version table provided by PowerMock team or to switch to JMockit to mock static and private methods.

How to Mock DataSource Dependency Injection Despite Being Accessible via Static Method

I'm using Mockito, DBUnit and HSQLDB to unit test my database code. I'm also writing integration tests of course.
I'm having trouble understanding how to inject a mocked DataSource into the system under test (class I'm testing). The DataSource is used for connection pooling, and therefore other classes can call a static method in the same class in order to retrieve an instance of this DataSource. This means that the DataSource is not injected into any constructors, anywhere, and so my tests don't have any constructors to inject the mocked DataSource into.
I'm getting around this by altering the logic of my real code to check if a private variable is null, and if so then use the injected DataSource (bad design since it's only needed for tests), otherwise it calls the static method to retrieve the connection pool's source (better design).
How do I inject a mocked DataSource into a class that doesn't have a constructor set up to accept it, because it can instead just call the static method to retrieve the dependency?
Class to Test
public DBConnection(DBSource dbSource) { // <--- Constructor only required for test purposes :(
this.dbSource = dbSource;
}
public final void createCompsDB() {
Connection conn = null;
Statement statement = null;
try {
if(dbSource==null){
conn = DBSource.getInstance().getConnection();
}else{
conn = dbSource.getConnection(); /** Likely bad design, since dbSource is only NOT null for tests, so that you can inject the mocked datasource :( */
}
statement = conn.createStatement();
statement.executeUpdate("CREATE DATABASE placesdb");
System.out.println("Database created...");
} catch (SQLException e) {
// ...
}
} finally {
// Close Resources...
}
}
}
Test Class -- Test Passes
public class DBConnectionTest {
final Statement statement = mock(Statement.class);
final Connection connection = mock(Connection.class);
final DBSource dataSource = mock(DBSource.class);
#Before
public void setUp() throws SQLException, IOException, PropertyVetoException {
when(dataSource.getConnection()).thenReturn(connection);
when(connection.createStatement()).thenReturn(statement);
}
#Test
public void testCreateCompDBIfNotAlready() throws Exception {
DBConnection dbConnection = new DBConnection(localDB, dataSource); /** This constructor is only needed for testing :( . How do I avoid it since all the classes I need to test don't require the dependency to be injected? */
dbConnection.createCompsDB();
verify(statement).executeUpdate("CREATE DATABASE PLACES");
}
}
DBSource.java
protected DBSource() throws IOException, SQLException, PropertyVetoException {
ds = new BasicDataSource();
ds.setDriverClassName("org.postgresql.Driver");
ds.setUsername("user");
ds.setPassword("pass");
ds.setUrl("jdbc:postgresql://localhost:5432/placesdb");
}
public static DBSource getInstance() { // <--- Static method means dependent classes don't need to accept injections
if (datasource == null) {
datasource = new DBSource();
return datasource;
} else {
return datasource;
}
}
public Connection getConnection() throws SQLException {
return this.ds.getConnection();
}
}
Mocking of the static class methods may be done with PowerMockito.
The test class should be something like this:
#RunWith(PowerMockRunner.class)
#PrepareForTest(DBSource.class)
public class DBConnectionTest {
#Mock
final Statement statement;
#Mock
final Connection connection;
#Mock
final DBSource dbsource;
#Before
public void setUp() throws SQLException, IOException, PropertyVetoException {
PowerMockito.mockStatic(DBSource.class);
when(DbSource.getInstance()).thenReturn(dbsource);
when(dbsource.getConnection()).thenReturn(connection);
when(connection.createStatement()).thenReturn(statement);
}
#Test
public void testCreateCompDBIfNotAlready() throws Exception {
DBConnection dbConnection = new DBConnection(localDB); // No test-only constructor anymore
dbConnection.createCompsDB();
verify(statement).executeUpdate("CREATE DATABASE PLACES");
}
}
You can read here more about mocking with PowerMock.

Eclipse Scout client unit tests with ScoutClientTestRunner

I am trying to create unit test with scout context and I can't find proper tutorial or example for it.
When I create test with ScoutClientTestRunner, I get error
java.lang.Exception: Client session class is not set. Either set the default client session using 'ScoutClientTestRunner.setDefaultClientSessionClass' or annotate your test class and/or method with 'ClientTest'
I try to set client session class like this :
#Before
public void setClassSession() throws Exception {
ScoutClientTestRunner.setDefaultClientSessionClass(ClientSession.class)
}
and
#BeforeClass
public void setClassSession() throws Exception {
ScoutClientTestRunner.setDefaultClientSessionClass(ClientSession.class);
}
I try to add #ClientTest to the class and to all methods but I still get same error.
How to set client session in tests if you use ScoutClientTestRunner ?
The ScoutClientTestRunner ensures that the JUnit tests are executed having all the Scout Context (OSGi and so on) available.
Your attempts with #Before or #BeforeClass are too late. You need to provide the Scout Context initialization parameters before that. As the exception message says, you have 2 possibilities:
(1) #ClientTest annotation
You can annotate test classes or methods with #ClientTest using the clientSessionClass parameter:
#RunWith(ScoutClientTestRunner.class)
#ClientTest(clientSessionClass = ClientSession.class)
public class DesktopFormTest {
#Test
public void test1() throws Exception {
//Do something requiring a scout context:
//for example instantiate a DesktopForm.
}
}
If necessary you can also do it at method level:
#RunWith(ScoutClientTestRunner.class)
public class DesktopFormTest {
#Test
#ClientTest(clientSessionClass = Client1Session.class)
public void test1() throws Exception {
//client session is an instance of Client1Session.
}
#Test
#ClientTest(clientSessionClass = Client2Session.class)
public void test2() throws Exception {
//client session is an instance of Client2Session.
}
}
(2) Defining a TestEnvironment
When the test is run (directly or using maven-tycho), a lookup for a fully qualified class org.eclipse.scout.testing.client.runner.CustomClientTestEnvironment is done.
The CustomClientTestEnvironment class should implement org.eclipse.scout.testing.client.runner.IClientTestEnvironment
The method setupGlobalEnvironment() is called once and can be used to define the default client session with ScoutClientTestRunner.setDefaultClientSessionClass(..). This method can also be used to register required services.
Here an example:
package org.eclipse.scout.testing.client.runner; // <= can not be changed.
// add imports
public class CustomClientTestEnvironment implements IClientTestEnvironment {
#Override
public void setupGlobalEnvironment() {
//Set client session:
ScoutClientTestRunner.setDefaultClientSessionClass(ClientSession.class);
}
#Override
public void setupInstanceEnvironment() {
}
}
Of course (1) and (2) are compatible. The second mechanism defines only the default and ClientSession configured with (1) will override the default.

Is it possible to test thru ActivityUnitTestCase a org.holoeverywhere.Activity?

I am coding my first ui test using holoEverywhere, I want to test a Activity which extends from org.holoeverywhere.app.Activity and I have this problem...
I tried to in the target app manifest this
And also in the manifest of the unit test project.
java.lang.IllegalStateException: Application instance isn't HoloEverywhere. Please sure that you extend class
android.test.mock.MockApplication from a
org.holoeverywhere.app.Application at
android.support.v4.app._HoloActivity.onInit(_HoloActivity.java:449) at
android.support.v4.app._HoloActivity.forceInit(_HoloActivity.java:207)
at org.holoeverywhere.app.Activity.onCreate(Activity.java:227) ......
This is my code:
public class MainActivityUnitTest extends
android.test.ActivityUnitTestCase<MainActivity> {
private MainActivity activity;
public MainActivityUnitTest () {
super(MainActivity.class);
}
#Override
protected void setUp() throws Exception {
super.setUp();
Context context = getInstrumentation().getTargetContext();
Intent intent = new Intent(context,
MainActivity.class);
startActivity(intent, null, null);
activity = getActivity();
}
The problem is your mock application (which is created by the unit test) is not a HoloEverywhere application. Call setApplication before calling startActivity. This will replace the used android.test.mock.MockApplication with an org.HoloEverywhere.app.Application.
#Override
protected void setUp() throws Exception
{
super.setUp();
setApplication(new org.HoloEverywhere.app.Application());
Intent intent = new Intent(getInstrumentation().getTargetContext(), DeclarerenActivity.class);
startActivity(intent, null, null);
}

Execute setup() once workaround causing TestSuit to fail

I have 2 files:
xxxxxTest.java
[refer this]
public class xxxxxTest extends TestCase {
// Run setup only once
public static Test suite() {
TestSetup setup = new TestSetup(new TestSuite(xxxxxTest.class)) {
protected void setUp() throws Exception {
//Some init which i need only once
}
protected void tearDown() throws Exception {
}
};
return setup;
}
public void testMyFirstMethodTest() {
assertNotNull(do stuff here);
}
}
AllTests.java
public class AllTests {
public static Test suite() {
TestSuite suite = new TestSuite("Test for xxxxxx");
//$JUnit-BEGIN$
suite.addTestSuite(xxxxxTest.class);
//$JUnit-END$
return suite;
}
}
So, my individual test(xxxxxTest.java) works fine, exactly as I want.When i run my test suite (AllTests.java), it fails, because the init in setup() i provided in xxxxxTest.java are not being executed.
Any suggestions?
UPDATE
I tried #BeforeClass in JUnit 4. But, it didn't help because in my ssetUp() method, I start an embedded Jetty server (server.start()), the server works fine with the code I posted, but when I do the same with #BeforeClass, it does not work.
In rare cases I also hacked around with static when using JUnit3.
In your case:
give the static{} initializer a try, maybe it works opposed to your static initialization.
if possible upgrade to JUnit4 and use #BeforeClass annotation (it is run once for a test-class). Your other JUnit3 test-classes should be runnable with JUnit4 test-runner also.
Similar to manuel's point: do you -need- to use JUnit 3? Then a class-level static{} initializer might be your best bet.
Otherwise, I recommend using JUnit 4, which has a construct which would might enjoy:
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class xxxxxTest {
#BeforeClass
public static void beforeClass() {
//Some init which i need only once
}
#Test
public void testMyFirstMethodTest() {
Assert.assertNotNull("");//do stuff here);
}
}