我很好奇是否有一种更简单的方法来模拟使用AOP的组件内的依赖项。
例如,我有一个使用CRUD方法来持久更改数据库的组件。对于审计日志记录,我认为我可以使用AOP,因此我不必将我的日志记录调用放在方法中。我遇到的问题是在单元测试期间,我想模拟在提供AOP的对象内使用的数据库和会话存储。我能够弄清楚如何伪造数据库和会话的唯一方法是创建一个新的模拟组件文件,扩展原始文件然后覆盖init方法。使用这种方法不是很灵活,因为我必须为简单的单元测试创建几个额外的文件。以下是一些测试代码:
这是使用di / 1 bean工厂创建的bean:
//customerBean.cfc
component accessors="true" extends="models.abstracts.AbstractModel" displayname="Customer" {
property name="ID" type="numeric" default="0";
property name="Name" type="string" length="100" default="<Unknown>" logEvents="update";
property name="Type" type="string" default="Homeowner" logEvents="update";
property name="Status" type="string" default="Active" logEvents="update";
public any function init(customerDAO) {
variables.DAO = arguments.customerDAO;
}
}
以下是customerBean扩展的组件:
//abstractModel.cfc
component accessors="true" {
public any function doCreate(required struct data) {
setID(save());
return getID();
}
}
这是AOP组件,它有两个需要模拟的依赖项:
//customerLogger.cfc
component accessors="true" {
property name="tableToLogTo" default="CustomerLogs" setter="false";
public any function init(LoggerServiceDAO, scopeStorage) {
variables.loggerServiceDAO = arguments.loggerServiceDAO;
variables.scopeStorage = arguments.scopeStorage;
}
public any function after(targetBean, methodName, args, result) {
variables.loggerServiceDAO.insertLog(method=arguments.methodName, user=variables.scopeStorage.get('session.user.id'));
}
}
以下是我用来获取CustomerBean的代码:
bf = new framework.aop(
folders="/models,/system,/tests/Mocks", config={transients=["entity", "process", "transients", "report", "forms"],transientPattern="Bean$"}
);
bf.intercept('CustomerBean', 'CustomerLoggerMock', 'doCreate');
customerBean = bf.getBean('CustomerBean', {customerDAO: customerDAOMock});
理想情况下,我想要做的是使用Testbox来模拟这两个对象,并使用漂亮的内置验证方法。这是可能的还是我不能创建所有这些模拟文件?