2009-09-22 74 views
3

下面是我寫的一個Web應用程序,我使用Java谷歌應用程序引擎構建一個類。我使用TestNG編寫了單元測試,並通過了所有測試。然後我在Eclipse中運行EclEmma以查看我的代碼的測試覆蓋率。所有功能顯示100%的覆蓋率,但該文件整體顯示約27%的覆蓋率。 73%的未被覆蓋的代碼來自哪裏?Java單元測試覆蓋率號不匹配

誰能幫助我瞭解EclEmma是如何工作的,以及爲什麼我得到的數字的差異?

package com.skaxo.sports.models; 

import javax.jdo.annotations.IdGeneratorStrategy; 
import javax.jdo.annotations.IdentityType; 
import javax.jdo.annotations.PersistenceCapable; 
import javax.jdo.annotations.Persistent; 
import javax.jdo.annotations.PrimaryKey; 

@PersistenceCapable(identityType= IdentityType.APPLICATION) 
public class Account { 

    @PrimaryKey 
    @Persistent(valueStrategy=IdGeneratorStrategy.IDENTITY) 
    private Long id; 

    @Persistent 
    private String userId; 

    @Persistent 
    private String firstName; 

    @Persistent 
    private String lastName; 

    @Persistent 
    private String email; 

    @Persistent 
    private boolean termsOfService; 

    @Persistent 
    private boolean systemEmails; 

    public Account() {} 

    public Account(String firstName, String lastName, String email) { 
     super(); 
     this.firstName = firstName; 
     this.lastName = lastName; 
     this.email = email; 
    } 

    public Account(String userId) { 
     super(); 
     this.userId = userId; 
    } 

    public void setId(Long id) { 
     this.id = id; 
    } 

    public Long getId() { 
     return id; 
    } 

    public String getUserId() { 
     return userId; 
    } 

    public void setUserId(String userId) { 
     this.userId = userId; 
    } 

    public String getFirstName() { 
     return firstName; 
    } 

    public void setFirstName(String firstName) { 
     this.firstName = firstName; 
    } 

    public String getLastName() { 
     return lastName; 
    } 

    public void setLastName(String lastName) { 
     this.lastName = lastName; 
    } 

    public String getEmail() { 
     return email; 
    } 

    public void setEmail(String email) { 
     this.email = email; 
    } 

    public boolean acceptedTermsOfService() { 
     return termsOfService; 
    } 

    public void setTermsOfService(boolean termsOfService) { 
     this.termsOfService = termsOfService; 
    } 

    public boolean acceptedSystemEmails() { 
     return systemEmails; 
    } 

    public void setSystemEmails(boolean systemEmails) { 
     this.systemEmails = systemEmails; 
    } 
} 

下面是上述類的測試代碼。

package com.skaxo.sports.models; 

import static org.testng.Assert.assertEquals; 
import static org.testng.Assert.assertNotNull; 
import static org.testng.Assert.assertTrue; 
import static org.testng.Assert.assertFalse; 

import org.testng.annotations.BeforeTest; 
import org.testng.annotations.Test; 

public class AccountTest { 

    @Test 
    public void testId() { 
     Account a = new Account(); 
     a.setId(1L); 
     assertEquals((Long) 1L, a.getId(), "ID"); 
     a.setId(3L); 
     assertNotNull(a.getId(), "The ID is set to null."); 
    } 

    @Test 
    public void testUserId() { 
     Account a = new Account(); 
     a.setUserId("123456ABC"); 
     assertEquals(a.getUserId(), "123456ABC", "User ID incorrect."); 
     a = new Account("123456ABC"); 
     assertEquals(a.getUserId(), "123456ABC", "User ID incorrect."); 
    } 

    @Test 
    public void testFirstName() { 
     Account a = new Account("Test", "User", "[email protected]"); 
     assertEquals(a.getFirstName(), "Test", 
       "User first name not equal to 'Test'."); 
     a.setFirstName("John"); 
     assertEquals(a.getFirstName(), "John", 
       "User first name not equal to 'John'."); 
    } 

    @Test 
    public void testLastName() { 
     Account a = new Account("Test", "User", "[email protected]"); 
     assertEquals(a.getLastName(), "User", 
       "User last name not equal to 'User'."); 
     a.setLastName("Doe"); 
     assertEquals(a.getLastName(), "Doe", 
       "User last name not equal to 'Doe'."); 
    } 

    @Test 
    public void testEmail() { 
     Account a = new Account("Test", "User", "[email protected]"); 
     assertEquals(a.getEmail(), "[email protected]", 
       "User email not equal to '[email protected]'."); 
     a.setEmail("[email protected]"); 
     assertEquals(a.getEmail(), "[email protected]", 
       "User email not equal to '[email protected]'."); 
    } 

    @Test 
    public void testAcceptedTermsOfService() { 
     Account a = new Account(); 
     a.setTermsOfService(true); 
     assertTrue(a.acceptedTermsOfService(), 
       "Accepted Terms of Service not true."); 
     a.setTermsOfService(false); 
     assertFalse(a.acceptedTermsOfService(), 
       "Accepted Terms of Service not false."); 
    } 

    @Test 
    public void testAcceptedSystemEmails() { 
     Account a = new Account(); 
     a.setSystemEmails(true); 
     assertTrue(a.acceptedSystemEmails(), "System Emails is not true."); 
     a.setSystemEmails(false); 
     assertFalse(a.acceptedSystemEmails(), "System Emails is not false."); 
    } 
} 

回答

2

這是一個猜測,但基於的Javadoc PersistenceCapable看起來類是通過額外的代碼編織由JDO增強實現接口。如果是這種情況,則很有可能附加代碼不在您的測試中。如果您刪除註釋並再次運行測試,您是否看到預期的覆蓋範圍?

從的Javadoc:

參考實現,JDO的增強修改類來實現PersistenceCapable之前加載類到運行環境。 Reference Enhancer還添加了代碼來實現由PersistenceCapable定義的方法。

您也可以嘗試使用像JAD反編譯檢查編譯的類來驗證類是否確實在編譯時附加的方法(或作爲前處理)編織而成。來自Javadoc的:

PersistenceCapable接口中的額外方法可能是通過預處理.java文件生成的,或者可能是直接從工具生成的。生成額外方法的確切技術不是由JDO指定的。

+0

我用JAD和它看起來像JDO代碼被插入到類。有沒有辦法讓測試覆蓋工具不看這個額外的代碼? – Dan 2009-09-22 22:16:20

+1

JDO增強遵循嚴格的合約......事情以「jdo」開頭。不應該很難忽略這些。 – DataNucleus 2009-09-23 17:21:13