I've done writing code on salesforce and in order to release the unit tests have to cover at least 75%.
What I am facing is that the classOne
that calls methods from classTwo
also have to cover classTwo
's unit test within classOne even though it is done in classTwo
file already.
File 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
}
}
File 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');
}
}
The result of testing MyClassOne would not return 100% test coverage because it says I have not covered MyClassTwo method2() part inside of MyClassOne file.
But I already wrote unit test for MyClassTwo inside of MyClassTwo file as you can see.
So does this mean I have to copy and paste the unit test in MyClassTwo file over to MyClassOne?
Doing so gives me 100% coverage but this seems really annoying and rediculous. Having same test in ClassA and ClassB....? Am I doing wrong or is this the way?
Having said, is it possible to create mock object in salesforce? I haven't figure how yet..
UDPATE
I re-wrote the code and updated above, this time for sure classOne test would not return 100% even though it is not calling classTwo method2()
If you really want to "unit" test, you should test the behavior of your class B AND the behavior of your class A, mocking the call to the class B method.
That's a tough conversation between mock lovers and others (Martin Fowler I think is not a "mocker").
Anyway. You should stop thinking about 100% coverage. You should think about:
Why am i testing?
How am i testing?
Here, i'd definitely go for 2 tests:
One test for the B class into the b class test file to be sure the B method is well implemented, with all the side effects, side values etc.
one test for the A class mocking the class B
What is a mock?
To stay VERY simple: A mock is a portion of code in your test which is gonna say: when the B class method is called, always return this value: "+++" .
By doing this, you allow yourself having a maintanable and modulable test suite.
In java, I love mockito : http://mockito.org/
Although one of my colleagues is lead maintainer for easymock: http://easymock.org/
Hope this helps. Ask me if you need further help.
EDIT SOME EXAMPLE
With Java and mockito:
Comments about Java mock libraries aren't very helpful in Salesforce world ;) At my projects we usually aimed for making our own test data in the test method, calling real functionality, checking the results... and whole test framework on Salesforce side is responsible for transaction rollback (so no test data is saved to DB in the end regardless whether the test failed or passed).
Anyway...
Masato, your classes do not compile (methods outside class scope,
public String hello()
without any String returned)... After I fixed it I simply right-clicked the MyClassA -> Force.com -> run tests and got full code coverage without any problems so your issue must lie somewhere else...Here's how it looks: http://dl.dropbox.com/u/709568/stackoverflow/masato_code_coverage.png
I'm trying to think what might have gone wrong... are you sure all classes compile and were saved on server side? Did you put test methods in same classes as functionality or in separate ones (generally I make separate class name with similar name like
MyClassATest
). If it's a separate class - on which file did you click "run tests"? Last but not least - if you're facing this issue during deployment from sandbox to production, make sure you selected all classes you need in the deployment wizard?I created an Apex class called TestHelper for all my mock objects. I use constants (static final) for values that I might need elsewhere and public static fields for objects. Works great and since no methods are used, no test coverage is needed.
}