3

我已经在 salesforce 上编写过代码,为了发布单元测试,必须至少覆盖75%

我面临的是,即使它已经在文件中完成classOne,调用方法的classTwo也必须覆盖classOne 中classTwo的单元测试。classTwo

文件 MyClassTwo

 public with sharing class ClassTwo {

    public String method1() {
        return 'one';
    }

    public String method2() {
        return 'two';
    }

    public static testMethod void testMethod1() {

        ClassTwo two = new ClassTwo();
        String out = two.method1();
        system.assertEquals(out, 'one'); //valid    
    }

    public static testMethod void testMethod2() {
        ClassTwo two = new ClassTwo();
        String out = two.method2();
        system.assertEquals(out, 'two'); // valid
    }

}

归档 MyClassOne

 public with sharing class ClassOne {

    public String callClassTwo() {
        ClassTwo foo = new ClassTwo();
        String something = foo.method1();

        return something;
    }

    public static testMethod void testCallClassTwo() {
        ClassOne one = new ClassOne();
        String out = one.callClassTwo();

        system.assertEquals(out, 'one');
    }
}

测试 MyClassOne 的结果不会返回 100% 的测试覆盖率,因为它说我没有覆盖 MyClassOne 文件中的 MyClassTwo method2() 部分。

但是我已经在 MyClassTwo 文件中为 MyClassTwo 编写了单元测试,如您所见。

那么这是否意味着我必须将 MyClassTwo 文件中的单元测试复制并粘贴到 MyClassOne 中?

这样做给了我 100% 的覆盖率,但这似乎真的很烦人和可笑。在 ClassA 和 ClassB 中进行相同的测试....?我做错了还是这样?

话虽如此,是否可以在 Salesforce 中创建模拟对象?我还没想好怎么办。。

http://sites.force.com/answers/ideaView?c=09a30000000D9xt&id=087300000007m3fAAA&returnUrl=/apex/ideaList%3Fc%3D09a30000000D9xt%26category%3DApex%2B%2526%2BVisualforce%26p%3D19%26sort%Dpopular

UDPATE

我重写了代码并在上面进行了更新,这一次确保 classOne 测试不会返回 100%,即使它没有调用 classTwo method2()

4

3 回答 3

3

关于 Java 模拟库的评论在 Salesforce 世界中不是很有帮助;)在我的项目中,我们通常的目标是在测试方法中制作我们自己的测试数据,调用真正的功能,检查结果......并且 Salesforce 方面的整个测试框架是负责事务回滚(因此无论测试失败还是通过,最终都不会将测试数据保存到数据库中)。

反正...

Masato,您的类无法编译(类范围之外的方法,public String hello()没有返回任何字符串)...修复它后,我只需右键单击 MyClassA -> Force.com -> 运行测试并获得完整的代码覆盖率,没有任何问题所以您的问题必须在其他地方...

这是它的外观:http ://dl.dropbox.com/u/709568/stackoverflow/masato_code_coverage.png

我试图思考可能出了什么问题......你确定所有类都编译并保存在服务器端吗?您是把测试方法放在与功能相同的类中还是放在单独的类中(通常我用类似的名称创建单独的类名,如MyClassATest)。如果它是一个单独的类 - 您在哪个文件上单击“运行测试”?最后但并非最不重要的一点 - 如果您在从沙盒部署到生产期间遇到此问题,请确保您在部署向导中选择了您需要的所有类?

于 2010-12-07T21:47:03.107 回答
1

如果你真的想“单元”测试,你应该测试你的 B 类的行为和你的 A 类的行为,模拟对 B 类方法的调用。

这是模拟爱好者和其他人之间的艰难对话(我认为马丁福勒不是“嘲弄者”)。

反正。您应该停止考虑 100% 的覆盖率。你应该考虑:

  • 我为什么要测试?

  • 我如何测试?

在这里,我肯定会进行 2 次测试:

  • 将 B 类的一项测试写入 b 类测试文件,以确保 B 方法得到很好的实现,包括所有副作用、副作用等。

  • 模拟 B 类的 A 类的一项测试

什么是模拟?

保持非常简单:模拟是测试中的一部分代码,它会说:当调用 B 类方法时,总是返回这个值: "+++" 。

通过这样做,您可以让自己拥有一个可维护和可模块化的测试套件。

在 java 中,我喜欢 mockito: http: //mockito.org/

虽然我的一位同事是 easymock 的主要维护者:http: //easymock.org/

希望这可以帮助。询问我是否需要进一步的帮助。

编辑一些例子

使用 Java 和 mockito:

public class aUTest {

    protected A a;

    @Mock protected B b;

    @Before
    public void setUp(){
        MockitoAnnotations.initMocks(this);
        a = new A();
        ReflectionTestUtils.setField(a, "b", b);
    }

        @Test
    public void test_A_method_should_not_throw_exception()
            when(b. execute()).thenReturn(true); //just an example of a return value from b. execute()
            Boolean result = a.testHello();

        // Assert
        Assert.assertEquals(true, result);
    }
于 2010-12-07T00:11:44.193 回答
1

我为所有模拟对象创建了一个名为 TestHelper 的 Apex 类。我将常量(静态最终)用于我可能在其他地方需要的值,并将公共静态字段用于对象。效果很好,因为没有使用任何方法,所以不需要测试覆盖。

public without sharing class TestHelper {
public static final string testPRODUCTNAME = 'test Product Name';
public static final string testCOMPANYID = '2508'; 

public static Account testAccount {
    get{
        Account tAccount = new Account(
            Name = 'Test Account',
            BillingStreet = '123 Main St',
            BillingCity = 'Dallas',
            BillingState = 'TX',
            BillingPostalCode = '75234',
            Website = 'http://www.google.com',
            Phone = '222 345 4567',                
            Subscription_Start_Date__c = system.today(),
            Subscription_End_Date__c = system.today().addDays(30),
            Number_Of_Seats__c = 1,
            companyId__c = testCOMPANYID,
            ZProduct_Name__c = testPRODUCTNAME);      
        insert tAccount;
        return tAccount; 
    }
}

}

于 2011-04-13T16:25:17.197 回答