You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 5 Next »

A UnitTest in Geode is a test with very narrow and well defined scope. Any complex dependencies and interactions are stubbed or mocked.

  • Should use JUnit 4 syntax
  • File name ends with *Test
  • Should use Category annotation of type UnitTest
  • Should complete in milliseconds 
  • Should generally test a single class
  • Typically uses white-box testing, uses Mocks/Fakes and helps guarantee internal quality (quality of code and class design)
  • Follows "A Set of Unit Testing Rules" by Michael Feathers
    • A UnitTest should not do any of the following:
      • communicate with a database
      • communicate across the network
      • access the file system
      • prevent the running of other unit tests in parallel
      • require anything special in the environment (such as editing config files or running an external process)

You would typically write a new UnitTest for each class you create. If you create a new class called RebalanceTask in the package org.apache.geode.internal.cache.control then you should also create a new test called RebalanceTaskTest in the same package but under src/test/java. This test should use JUnit 4 syntax and have a JUnit Category of type org.apache.geode.junit.categories.UnitTest. All dependencies should generally be Mocks or Spies created with Mockito or fakes that are coded specifically for use by the test in order to isolate the code being tested to just RebalanceTask. The test should not use the network or file system and it should complete within milliseconds.

If you are identifying and ultimately fixing a bug, then you should write at least one new test that reproduces the bug which will then validate its fix. If possible, write a UnitTest which reproduces some part of the bug and use *RegressionTest as the class name suffix. If the bug involves a concurrency problem in the class RebalanceTask which results in throwing a NullPointerException then you might write a new test class called RebalanceTaskInitializedAtomicallyRegressionTest. If you cannot reproduce the bug in a UnitTest then do so in an IntegrationTest or DistributedTest instead. If you can reproduce the bug in a UnitTest but coverage of the bug and its fix would be even better with an IntegrationTest regression test, then you should write both tests as these will provide complementary but slightly different test coverage.

It's not absolutely necessary to introduce a new *RegressionTest class for covering a bug. If new regression test coverage fits better within an existing test class, then add one or more new tests to that existing test class but include javadocs on the new test methods which includes the GEODE JIRA ticket number and its summary at a minimum.

Examples of some good UnitTests:

  • TODO

Examples of good RegressionTests which are UnitTests:

  • CacheServerBridgeClientMembershipRegressionTest

General form of a UnitTest:

package org.apache.geode.internal.cache.control;
 
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import org.apache.geode.test.junit.categories.UnitTest;

@Category(UnitTest.class)
public class RebalanceTaskTest {
 
  private RebalanceTask rebalanceTask;
  private RebalanceStats rebalanceStats;
 
  @Before
  public void setUp() {
    // arrange: create the SUT (system under test) and its dependencies
    rebalanceStats = mock(RebalanceStats.class);
    rebalanceTask = new RebalanceTask(rebalanceStats);
  }
 
  @After
  public void tearDown() {
    // cleanup anything that might affect a later test or that uses any resources
  }
 
  @Test
  public void execIncrementsRebalanceStats() throws Exception {
    // act: do something like invoke exec
    // assert: assertThat expected behavior or interaction with dependency occurred
  }
}

 

more info

  • No labels