Tôi có một POJO có sử dụng một dịch vụ để làm điều gì đó:Sử dụng Groovy metaclass ghi đè lên phương pháp
public class PlainOldJavaObject {
private IService service;
public String publicMethod(String x) {
return doCallService(x);
}
public String doCallService(String x) {
if(service == null) {
throw new RuntimeException("Service must not be null");
}
return service.callX(x);
}
public interface IService {
String callX(Object o);
}
}
Và tôi có một trường hợp thử nghiệm Groovy:
class GTest extends GroovyTestCase {
def testInjectedMockIFace() {
def pojo = new PlainOldJavaObject(service: { callX: "very groovy" } as IService)
assert "very groovy" == pojo.publicMethod("arg")
}
def testMetaClass() {
def pojo = new PlainOldJavaObject()
pojo.metaClass.doCallService = { String s ->
"no service"
}
assert "no service" == pojo.publicMethod("arg")
}
}
Phương pháp thử nghiệm đầu tiên, testInjectedMockIFace
công trình như mong đợi: POJO được tạo với triển khai động IService
. Khi callX
được gọi, nó đơn giản trả về "rất hấp dẫn". Bằng cách này, dịch vụ được chế giễu.
Tuy nhiên tôi không hiểu tại sao phương pháp thứ hai, testMetaClass
không hoạt động như mong đợi nhưng thay vào đó ném NullPointerException khi cố gắng gọi callX
trên đối tượng dịch vụ. Tôi nghĩ rằng tôi đã ghi đè phương thức doCallService
với dòng này:
pojo.metaClass.doCallService = { String s ->
Tôi đang làm gì sai?
Cảm ơn!
Một điều cần lưu ý ở đây là khi bạn thao tác metaClass của Class, mọi cá thể từ điểm đó trở đi sẽ được thao tác. Điều này có thể có tác động lớn đến các thử nghiệm khác chạy trong cùng một phiên. Khi bạn thao tác một cá thể của một lớp, chỉ có cá thể đó bị ảnh hưởng. –