Can AspectJ replace "new X" with "new SubclassOfX" in third-party library code? -


i looking @ aspectj see if perhaps can use in our test suite.

we have rather large third party java communications library hardwired use own classes (which not implement interfaces) in turn mean need physical backend present , correctly configured able run tests.

i looking @ our options removing restriction. possibility create subclass of troublesome classes , ask aspectj replace "new x" "new oursubclassofx" when loading third party library, new aspectj , brief skimming of documentation not typical use case.

can aspectj this? configuration snippet be?

yes, possible. let assume have hard-wired class, possibly fetching database, , want mock via aspect:

package de.scrum_master.aop.app;  public class hardwired {     private int id;     private string name;      public hardwired(int id, string name) {         this.id = id;         this.name = name;     }      public void dosomething() {         system.out.println("fetching values database");     }      public int getsomething() {         return 11;     }      @override     public string tostring() {         return "hardwired [id=" + id + ", name=" + name + "]";     } } 

then there little driver application using class (not interface):

package de.scrum_master.aop.app;  public class application {     public static void main(string[] args) {         hardwired hw = new hardwired(999, "my object");         system.out.println(hw);         hw.dosomething();         system.out.println(hw.getsomething());     } } 

the output follows:

hardwired [id=999, name=my object] fetching values database 11 

now define derived mock class should replace original testing purposes:

package de.scrum_master.aop.mock;  import de.scrum_master.aop.app.hardwired;  public class hardwiredmock extends hardwired {     public hardwiredmock(int id, string name) {         super(id, name);     }      @override     public void dosomething() {         system.out.println("mocking database values");     }      @override     public int getsomething() {         return 22;     }      @override     public string tostring() {         return "mocked: " + super.tostring();     } } 

and define aspect simple pointcut , advice replace original value during each constructor call:

package de.scrum_master.aop.aspect;  import de.scrum_master.aop.app.hardwired; import de.scrum_master.aop.mock.hardwiredmock;   public aspect mockinjector {     hardwired around(int p1, string p2) : call(hardwired.new(int, string)) && args(p1, p2) {         return new hardwiredmock(p1, p2);     } } 

the output changes desired:

mocked: hardwired [id=999, name=my object] mocking database values 22 

you once per class , constructor , fine. in order generalise approach need joinpoint properties and, depending on how far want go, maybe reflection, here pretty straightforward. enjoy!


Comments

Popular posts from this blog

php - Why I am getting the Error "Commands out of sync; you can't run this command now" -

linux - Does gcc have any options to add version info in ELF binary file? -

java - Are there any classes that implement javax.persistence.Parameter<T>? -