diff --git a/tests/phpunit/CRM/Member/Form/MembershipTest.php b/tests/phpunit/CRM/Member/Form/MembershipTest.php
index 09476038bc60..c5702268c72d 100644
--- a/tests/phpunit/CRM/Member/Form/MembershipTest.php
+++ b/tests/phpunit/CRM/Member/Form/MembershipTest.php
@@ -138,6 +138,7 @@ public function tearDown() {
       )
     );
     $this->callAPISuccess('contact', 'delete', array('id' => 17, 'skip_undelete' => TRUE));
+    $this->callAPISuccess('contact', 'delete', array('id' => 18, 'skip_undelete' => TRUE));
     $this->callAPISuccess('contact', 'delete', array('id' => 23, 'skip_undelete' => TRUE));
     $this->callAPISuccess('relationship_type', 'delete', array('id' => 20));
   }
@@ -684,6 +685,126 @@ public function testFormStatusUpdate() {
     $this->assertEquals($membership['status_id'], $previousStatus);
   }
 
+  /**
+   * CRM-20946: Test the financial entires especially the reversed amount,
+   *  after related Contribution is cancelled
+   */
+  public function testFinancialEntiriesOnCancelledContribution() {
+    $form = $this->getForm(NULL);
+    $form->preProcess();
+    $this->createLoggedInUser();
+
+    // create a price-set of price-field of type checkbox and each price-option corrosponds to a membership type
+    $priceSet = $this->callAPISuccess('price_set', 'create', array(
+      'is_quick_config' => 0,
+      'extends' => 'CiviMember',
+      'financial_type_id' => 1,
+      'title' => 'my Page',
+    ));
+    $priceSetID = $priceSet['id'];
+    // create respective checkbox price-field
+    $priceField = $this->callAPISuccess('price_field', 'create', array(
+      'price_set_id' => $priceSetID,
+      'label' => 'Memberships',
+      'html_type' => 'Checkbox',
+    ));
+    $priceFieldID = $priceField['id'];
+    // create two price options, each represent a membership type of amount 20 and 10 respectively
+    $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', array(
+        'price_set_id' => $priceSetID,
+        'price_field_id' => $priceField['id'],
+        'label' => 'Long Haired Goat',
+        'amount' => 20,
+        'financial_type_id' => 'Donation',
+        'membership_type_id' => 15,
+        'membership_num_terms' => 1,
+      )
+    );
+    $pfvIDs = array($priceFieldValue['id'] => 1);
+    $priceFieldValue = $this->callAPISuccess('price_field_value', 'create', array(
+        'price_set_id' => $priceSetID,
+        'price_field_id' => $priceField['id'],
+        'label' => 'Shoe-eating Goat',
+        'amount' => 10,
+        'financial_type_id' => 'Donation',
+        'membership_type_id' => 35,
+        'membership_num_terms' => 2,
+      )
+    );
+    $pfvIDs[$priceFieldValue['id']] = 1;
+
+    // register for both of this memberships via backoffice membership form submission
+    $params = array(
+      'cid' => $this->_individualId,
+      'join_date' => date('m/d/Y', time()),
+      'start_date' => '',
+      'end_date' => '',
+      // This format reflects the 23 being the organisation & the 25 being the type.
+      "price_$priceFieldID" => $pfvIDs,
+      "price_set_id" => $priceSetID,
+      'membership_type_id' => array(1 => 0),
+      'auto_renew' => '0',
+      'max_related' => '',
+      'num_terms' => '2',
+      'source' => '',
+      'total_amount' => '30.00',
+      //Member dues, see data.xml
+      'financial_type_id' => '2',
+      'soft_credit_type_id' => '',
+      'soft_credit_contact_id' => '',
+      'payment_instrument_id' => 4,
+      'from_email_address' => '"Demonstrators Anonymous" <info@example.org>',
+      'receipt_text_signup' => 'Thank you text',
+      'payment_processor_id' => $this->_paymentProcessorID,
+      'record_contribution' => TRUE,
+      'trxn_id' => 777,
+      'contribution_status_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_DAO_Contribution', 'contribution_status_id', 'Pending'),
+      'billing_first_name' => 'Test',
+      'billing_middlename' => 'Last',
+      'billing_street_address-5' => '10 Test St',
+      'billing_city-5' => 'Test',
+      'billing_state_province_id-5' => '1003',
+      'billing_postal_code-5' => '90210',
+      'billing_country_id-5' => '1228',
+    );
+    $form->testSubmit($params);
+
+    // cancel the related contribution via API
+    $contribution = $this->callAPISuccessGetSingle('Contribution', array(
+      'contact_id' => $this->_individualId,
+      'contribution_status_id' => 2,
+    ));
+    $this->callAPISuccess('Contribution', 'create', array(
+      'id' => $contribution['id'],
+      'contribution_status_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_DAO_Contribution', 'contribution_status_id', 'Cancelled'),
+    ));
+
+    // fetch financial_trxn ID of the related contribution
+    $sql = "SELECT financial_trxn_id
+     FROM civicrm_entity_financial_trxn
+     WHERE entity_id = %1 AND entity_table = 'civicrm_contribution'
+     ORDER BY id DESC
+     LIMIT 1
+    ";
+    $financialTrxnID = CRM_Core_DAO::singleValueQuery($sql, array(1 => array($contribution['id'], 'Int')));
+
+    // fetch entity_financial_trxn records and compare their cancelled records
+    $result = $this->callAPISuccess('EntityFinancialTrxn', 'Get', array(
+      'financial_trxn_id' => $financialTrxnID,
+      'entity_table' => 'civicrm_financial_item',
+    ));
+    // compare the reversed amounts of respective memberships after cancelling contribution
+    $cancelledMembershipAmounts = array(
+      -20.00,
+      -10.00,
+    );
+    $count = 0;
+    foreach ($result['values'] as $record) {
+      $this->assertEquals($cancelledMembershipAmounts[$count], $record['amount']);
+      $count++;
+    }
+  }
+
   /**
    * Test the submit function of the membership form.
    */
diff --git a/tests/phpunit/CRM/Member/Form/dataset/data.xml b/tests/phpunit/CRM/Member/Form/dataset/data.xml
index 65a279e9548b..9655cea473ad 100644
--- a/tests/phpunit/CRM/Member/Form/dataset/data.xml
+++ b/tests/phpunit/CRM/Member/Form/dataset/data.xml
@@ -10,6 +10,15 @@
     first_name="Joe"
     last_name="Blow"
   />
+  <civicrm_contact
+    id="18"
+    contact_type="Individual"
+    is_opt_out="0"
+    display_name="Alex Blow"
+    sort_name="Blow, Alex"
+    first_name="Alex"
+    last_name="Blow"
+  />
   <civicrm_contact
     id="23"
     contact_type="Organization"
@@ -17,6 +26,13 @@
     display_name="Save The Dollars"
     organization_name="Save The Dollars"
   />
+  <civicrm_contact
+    id="32"
+    contact_type="Organization"
+    is_opt_out="0"
+    display_name="Save The Rupees"
+    organization_name="Save The Rupees"
+  />
 
   <civicrm_relationship_type
     id="20"
@@ -48,5 +64,15 @@
     relationship_type_id="20"
     financial_type_id="2"
    />
-
+   <civicrm_membership_type
+     id="35"
+     domain_id="1"
+     name="AnnualRolling1"
+     member_of_contact_id="32"
+     duration_unit="year"
+     duration_interval="1"
+     period_type="rolling"
+     relationship_type_id="20"
+     financial_type_id="2"
+   />
 </dataset>