Some of our CFCs use custom tags to get some of their work done. I’d like to keep our components nice and independent for unit testing, but currently I’m not aware of any way to mock the custom tags in our tests. Does anyone know of a way to do this (either with MockBox or with some CF cleverness)?
I’d like to avoid making a pass-through or wrapper for the custom tag, especially where we make use of custom child tags - would make it tricky to still use the existing custom tags w/o getting into a very messy syntax I’m guessing.
That is a very good question, however my guess is that these fall into the views or usability side of things. Where as MockBox is really for components.
Even as a feature request, I think mocking Custom Tags would be impossible.
A lot of our custom tags are for the view layer, but the specific case I’m worried about is a custom layer on top of cfmail that adds some functionality and business logic. This tag we end up using quite a bit in our controllers.
I was kind of afraid that the answer might be ‘no can do, dreamer’
No worries. We may end up rewriting this one specific tag to be a component we can mock - I just like that the custom tag’s syntax maps so well to the underlying cfmail’s syntax.
What solutions are people using to handle unit testing when things like cfmail/cffile are involved that aren’t easy to mock and don’t allow for isolated testing well if they’re used in a function? I know for cfquery we appropriately move the query to a DAO that we can mock (with the very handy querysim), but what about the mail and file cases (and any other things where there are tendrils out into not-easily-mockable areas)?
Jon
Yes, but MockBox is about creating an empty component. There is no way to create an empty CustomTag with the same name, it would be wrappers in TestBox or Mockbox. anyway.
Sorry the question below… I can’t say what others are doing, but if it was me you would have to write a wrapper for any internal feature to ColdFusion. As I use ColdBox, there is a plugin component that is better suited to mocking here than using cfmail.
But I am guessing your not using ColdBox here.
Our app is a mix of pure CF pages, model-glue, and (thankfully/recently) ColdBox. This particular question is part of our attempt to understand the best way to refactor our code as we migrate from model-glue to ColdBox. I’m in the middle of recommending that a function that uses our custom mail tag be migrated to the ColdBox part of our app and was scratching my head about what to recommend for testing the function where the custom tag was involved.
I like the idea of using a plugin (or a module - I think Luis mentioned plugins are going away in 4.0) that can decouple/abstract the actual mailing bits from the other code in the app. I haven’t explored the core plugins much yet, but the MailService looks like it may be what we need. I just noticed this section, too, in the docs that shows how we could add the custom functionality on top of the core mail plugin for what we need: http://wiki.coldbox.org/wiki/Plugins.cfm#Extending/Overriding_Core_Plugins
Thanks for helping me sort through this - gives me a good direction to go with it.
No plugins are remaining, they just wont be called plugins.
And ColdBox already has a mail plugin (Model)…
property name=“mailService” inject=“coldbox:plugin:MailService”;
var bodyTokens = {
authorName = author.getName(),
authorRole = author.getRole().getRole(),
authorEmail = author.getEmail(),
authorURL = CBHelper.linkAdmin(“authors.editor.authorID.#author.getAuthorID()#”),
currentAuthor = currentAuthor.getName(),
currentAuthorEmail = currentAuthor.getEmail()
};
var mail = mailservice.newMail(to=settings.cb_site_email,
from=settings.cb_site_outgoingEmail,
subject="#settings.cb_site_name# - Author Created - #bodyTokens.authorName#",
bodyTokens=bodyTokens,
type=“html”,
server=settings.cb_site_mail_server,
username=settings.cb_site_mail_username,
password=settings.cb_site_mail_password,
port=settings.cb_site_mail_smtp,
useTLS=settings.cb_site_mail_tls,
useSSL=settings.cb_site_mail_ssl);
// generate content for email from template
mail.setBody( renderer.get().renderLayout(
view="/contentbox/email_templates/author_new",
layout=“email”,
module=“contentbox-admin”,
args = { gravatarEmail= currentAuthor.getEmail() }
));
// send it out
mailService.send( mail );