Coldfusion - Cant find testbox - unit-testing

I have a coldfusion application that i would like to start writing unit tests for. I found testbox, and think it would be a great testing library to use. I followed the installation instructions, but my cold fusion app is throwing an error when i try to run my first test.
I downloaded the zip file and put in in my C drive, added the mapping to my application.cfc, but it throws the following error (see below). Can anyone help me debug why it can't find textbox?
Error
Invalid CFML construct found on line 2 at column 1.
ColdFusion was looking at the following text:
testbox
The error occurred in C:/inetpub/wwwroot/tests/main.cfc: line 2
1 : // Create TestBox object
2 : testbox = new testbox.system.TestBox();
3 : ​
4 : // You can add fluent specs via addDirectory(), addDirectories(), addBundles()
Application.cfc
component {
this.name = "A TestBox Runner Suite " & hash( getCurrentTemplatePath() );
// any other application.cfc stuff goes below:
this.sessionManagement = true;
// any mappings go here, we create one that points to the root called test.
this.mappings[ "/tests" ] = getDirectoryFromPath( getCurrentTemplatePath() );
// Map back to its root
this.mappings[ "/testbox" ] = expandPath( "C:/testbox/" );
// any orm definitions go here.
// request start
public boolean function onRequestStart( String targetPage ){
return true;
}
}
main.cfc
// Create TestBox object
testbox = new testbox.system.TestBox();
​
// You can add fluent specs via addDirectory(), addDirectories(), addBundles()
testbox.addDirectory( "specs" );
​
// Run tests and produce reporter results
testbox.run()
​
// Run tests and get raw testbox.system.TestResults object
testbox.runRaw()
​
// Run tests and produce reporter results from SOAP, REST, HTTP
testbox.runRemote()
test box directory.

Try changing your mapping to C:\testbox\testbox\ , or move the contents of your \testbox\testbox folder up one level. I think you may have unzipped to one too many folders. Is there a system folder inside the second testbox folder? You want to make sure that your mapping points to the folder containing your actual TestBox files.

Related

Calling Java JAR functions

I'm attempting to connect to Java (JAR) libraries to communicate with the "QuickBooks Merchant Services API".
Each call to the API requires an OAuth2 access token. My first step is to use the Java SDK that QuickBooks provides to get the access token.
I downloaded the "jar-with-dependencies.jar" option from this page. According to Maven, 6.0.1 is the current version.
https://search.maven.org/search?q=a:oauth2-platform-api
I created a folder named "java" off of the root of the web site and stored this file in that folder.
oauth2-platform-api-6.0.1-jar-with-dependencies.jar
In Application.cfc, I added this line of code:
<!--- Application.cfc snippet --->
<cfset this['javaSettings'] = {
LoadPaths = ["#expandPath('/java')#"]
,loadColdFusionClassPath = true
,reloadOnChange = true
,watchInterval = 100
,watchExtensions = "jar,class,xml"
}>
In a test.cfm file I have the following lines of code in a function:
variables['oauth2Config'] = createObject("java", "com.intuit.oauth2.config.OAuth2Config").OAuth2ConfigBuilder(arguments.clientId, arguments.clientSecret).callDiscoveryAPI(Environment.SANDBOX).buildConfig();
In an example on the developer.intuit.com web site, the Java code looks like this:
OAuth2Config oauth2Config = new OAuth2Config.OAuth2ConfigBuilder("clientId", "clientSecret").callDiscoveryAPI(Environment.SANDBOX).buildConfig();
When I run the code, I get the following error message.
Class not found: com.intuit.oauth2.config.OAuth2Config
I have swapped out the "LoadPaths" key with several different variants but all result in the same error.
LoadPaths = ["/java"]
LoadPaths = ["./java"]
LoadPaths = ["./java/oauth2-platform-api-6.0.1-jar-with-dependencies.jar"]
I have tried modifying the initialization call:
local['oauth2Config'] = createObject("java", "OAuth2Config").OAuth2ConfigBuilder(arguments.clientId, arguments.clientSecret).callDiscoveryAPI(Environment.SANDBOX).buildConfig();
That resulted in basically the same kind of error:
Class not found: OAuth2Config
I'm pretty sure that I'm doing something wrong in the this.javaSettings struct in Application.cfc. I was hoping that the Java JAR approach would be easier, but I may end up using the REST API that Intuit has. I still have to use OAuth2 and I'm not sure if the cfoauth tag/function will work with this system.
Let me know if you see anything that will help me get past this problem.
CF can't find OAuth2ConfigBuilder because it's inner class, which requires a slightly different syntax:
createObject("java", "com.intuit.oauth2.config.OAuth2Config$OAuth2ConfigBuilder");
Environment is also a class within the jar. You must create a reference to it before using the constant Environment.SANDBOX
Even after fixing those issues, a brief test with CF2016 threw a LinkageError due to the inclusion of slf4j within the custom jar, while also loading the jars from CF/lib (which includes slf4j too). Switching to loadColdFusionClassPath = false seemed to get past that error.
java.lang.LinkageError: loader constraint violation: when resolving
method
"org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()Lorg/slf4j/ILoggerFactory;"
the class loader (instance of
coldfusion/runtime/java/JavaDynamicClassLoader)
...
Application.cfc
this['javaSettings'] = {
LoadPaths = ["#expandPath('/java')#"]
,loadColdFusionClassPath = false
, ...
};
Code:
variables['environ'] = createObject("java", "com.intuit.oauth2.config.Environment");
variables['builder'] = createObject("java", "com.intuit.oauth2.config.OAuth2Config$OAuth2ConfigBuilder");
variables['oauth2Config'] = variables['builder'].init( arguments.clientId, arguments.clientSecret).
callDiscoveryAPI( variables['environ'].SANDBOX ).buildConfig();

Updating Ember.js environment variables do not take effect using in-repo addon config() method on ember serve

My goal here is to create an auto-increment build number that updates both on ember build and ember serve. In the end, if I can only use this on build, that's totally ok.
I originally asked this question:
In-repo addon writing public files on build causes endless build loop on serve
In that I was attempting to solve this problem by writing out JSON files. The problem was mostly solved, but not using ember serve.
Instead of doing that, I'm now trying to update the local environment. But this is having a similar problem with ember serve. I've got the build number incrementing fine. I can use the config() method to set custom/dynamic variables in the environment. The problem I'm having is that the even though I can log the change in terminal when config() is called, and I can see it run on serve when files change, I don't see the changes in browser when I output Ember's ENV using ember serve. Here's my addon's methods so far.
Note: the appNumberSetup() function is just reading a local json file in the project root and updating the build number. That's working fine. Anything about pubSettingsFile can be ignored, I won't be using that moving forward.
init(parent, project) {
this._super.init && this._super.init.apply(this, arguments);
// we need to setup env in init() so config() and prebuild()
// will see update immediately
this.settingsFile = path.resolve(this.appDir, this.settingsFileName);
this.addonPubDataPath = path.resolve(this.appDir, 'lib', this.name, 'inc', 'public', 'build-data-output');
this.pubSettingsFile = path.resolve(this.addonPubDataPath, this.pubSettingsFileName);
// this only checks for .env variables and sets defaults
this.dotEnvSetup();
// must set this so prebuild skips processing a build number on build
// else we get build number incremented twice on first run
// then appNumberSetup() disables so subsequent serve preBuild() will run.
this.skipPreBuild = true;
this.appNumberSetup();
},
// this sends our created settings data to ENV.localBuildSettings in app
config(environment, appConfig){
// this 'buildme' is just an experiment
let x = `buildme${this.buildNumber}`;
let r = {
localBuildSettings: this.settings
};
r[`buildme${this.buildNumber}`] = this.buildNumber;
this.dlog("Config ran...");
this.dlog(JSON.stringify(r, null, 4));
return r;
},
preBuild: function(result){
// init() disables preBuild() here, but subsequent builds with serve still
// run appNumberSetup() to update this.settings for env and JSON
if(this.skipPreBuild === true){
this.skipPreBuild = false;
}
else {
// only run here after init runs
this.appNumberSetup();
}
// don't do this... write file makes endless loop on serve
// this.saveSettingsFile(this.pubSettingsFile, this.settings);
},
this.settings is a local variable in addon and it updated on build/serve, the JSON looks like this:
{
"appVersion": 911,
"appBuildNumber": 7117
}
Is there a way to update Ember's ENV with dynamic data? (like a new build number)
The addon config() appears to run on each change in ember serve, and it shows the build number in terminal output. But it looks like that runs after postBuild(). Maybe that's why I don't see the changes. Is there a way to update that environment during preBuild()?
I'm not sure of the specifics but ember-cli-new-version does this. During the build stage they create a VERSION.txt file, might even do what you need already without needing to write it yourself.

platformwebservice not used anymore after I have implemented custom webservice

I need to custom some DTO and Ressources from platformwebservices, so I follow the Hybris instruction to create a custom extension for WEB Services.
You can mark one of your own extensions as a webservice extension:
1 - Create a new extension using the yempty template.
2 - Add the new extension to localextensions.xml file.
3 - In the command line go to the platform directory and call: ant.
4 - In the command line go to the new extension directory and call ant webservice_nature -Dextname=customextension.
Running this task gives the selected extension a nature of platformwebservices extension. It results in:
1 - Generation of a new web.xml file. If one already exists, it is renamed to web.xml.old.
2 - Generation of the extension_name -web-spring.xml located in extension_name /resources directory, unless it already exists there.
3 - An additional entry in the Platform's local.properties file,
file : local.properties
webservice.module={extensionname}
I can compile (ant clean all) and launch the server but when I try do execute a request in postman like : https://localhost:9002/ws410/rest/products/
it's not working, it gives me a 404 error.
if I remove my customExtension in local extension.xml and "webservice.module={extensionname}" in local.properties
and execute the request (same url) It's give a 200 with the correct response.
The fact is, when my customExtension is set the platformwebservices is not used anymore.

Downloading a file using WireMoc

I'm new to WireMoc. How do i go about Downloading a file using WireMoc stubbing framework?
This is what i have so far
var stub = FluentMockServer.Start(new FluentMockServerSettings
{
Urls = new[] { "http://+:5001" },
StartAdminInterface = true
});
stub.Given(
Request.Create()
.WithPath("/myFile")
.UsingPost()
.WithBody("download file"))
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithHeader("Content-Type", "application/multipart")
you can use withBodyFile api of wiremock
stubFor(get(urlEqualTo("/body-file"))
.willReturn(aResponse()
.withBodyFile("path/to/myfile.xml")));
However
To read the body content from a file, place the file under the __files directory. By default this is expected to be under src/test/resources when running from the JUnit rule. When running standalone it will be under the current directory in which the server was started. To make your stub use the file, simply call bodyFile() on the response builder with the file’s path relative to __files:
But you can set custom path while starting wiremock using
wireMockServer = new WireMockServer(wireMockConfig().port(portNumber).usingFilesUnderClasspath("src/main/resources/"));
Now it will look for files in /src/main/resources/__files/
The source for above information
http://wiremock.org/docs/stubbing/
https://github.com/tomakehurst/wiremock/issues/129

TDD for a medium complexity method

I've been out of touch with TDD for some time, and am very rusty. I'd appreciate some suggestions on how to TDD the method described below.
The method must find a web.config file in a user supplied application directory. It must then extract and return a connection string from that config file.
It returns null if for any reason the connection string isn't found, be it a bad path, no web.config, or no connection string in web.config.
My initial thoughts are to write a test with setup that creates a directory and writes a web.config file with a connection string. The test would then call my method with the created path and expect a non-null value back, and my initial test run would fail because my method stub always returns null.
Then, implement the method, and run the test expecting a pass. Then, as a pre-test (I forget the term), delete the created directory, and call the method expecting a null value.
First, I wouldn't have the method both find the file and extract the connection string. If your framework doesn't already have a method to determine if a file exists in a given directory, write a method to do then, once you have a file, write a method to extract the connection string from an open stream. For testing, then, you could supply a memory stream instead of having to actually create a directory and file.
Second, if you aren't depending on a failed compile being your first failing test, then write your first attempt at the method to throw a NotImplementedException. It's a small step, but when you write your first test, at least it will fail. Of course, the first test on an empty stream will expect it to return null and the first code you write will be return null, but that's ok. Your next test will force you to change it. Continue on from there until you've got your completed methods.
You appear to have several TestCases with several distinct setUp fixtures.
The FoundDirectory TestCase. The setUp creates the expected, valid file.
This can have several subclasses.
A connection string not found TestCase. The setUp creates the expected, but invalid file.
A bad path TestCase. The setUp creates the expected, but invalid file.
A no web.config TestCase. The setUp creates the expected, but invalid file.
A no connection string in web.config TestCase. The setUp creates the expected, but invalid file.
The DidntFindDirectory TestCase. The setUp assures that the directory doesn't exist.
The DidntFindFile TestCase. The setUp creates the directory but no file.
Make the object that hold you method (or the method itself) dependent on a IConfigLoader of some sort, that you would be able to mock :
public interface IConfigLoader
{
XmlReader LoadAppConfigFrom(string path);
}
Use it from your method to get the XML file you want to parse.
I suggest that the story in your question mixes several issues:
finding and opening a file,
loading data into a "configuration" (however represented)
attempting to get a specific parameter from a "configuration"
Point 3 is now a matter of how a Configuration behaves, and can be developed in TDD fashion.
Point 2 is now a matter of how a Configuration is constructed (e.g by a ConfigurationLoader), and can be developed in TDD fashion (e.g. against a StringReader).
Point 1 is now a matter of whether you can open a Reader for a specified file path. It is easy to add after completing point 2.