Using testbox to test a component, is there a way ...
# testing
b
Using testbox to test a component, is there a way to assert that a component has a method? For example to make sure that a model component has a
setSomeProp()
method that exists on it?
b
You can call it 😉
The most direct way in CF is to use
structKeyExists()
paired with the
isCustomFunction()
BIF
Copy code
structKeyExists( myCFC, "myMethod" ) && isCustomFunction( myCFC.myMethod )
👀 1
Assert that is true
Or there is prolly an expectation to do at least the first part of that
t
In the "you can call it" vein, I think it would be
expect(() -> setSomeProp()).notToThrow()
b
Structkeyexists() works, ty. Not to throw is another good one to know 🙏
Weird,
structkeyexists
passes, but calling the method on the model with
.nottothrow()
fails with: The incoming function DID throw an exception of type [expression] with message [The function [target] does not exist on the Object,only the following functions are available: ... Odd thing is other assertions calling the same methods pass 😕
t
yup, that's weird. Sorry I don't have anything useful.
b
can you show your code?
Try taking the code out of the not to throw expectation and just run it directly to see the full error that's getting thrown
b
Yeah let me get the code. Running the code separately throws no error
Copy code
it("should have all the right props on the model", () =>  {
		local.model = createObject("component", "path.to.my.model");

		expect(structKeyExists(local.model, "setSomeProp")).toBeTrue(); // passes

		expect(local.model.setSomeProp(someArg)).notToThrow(); // fails
	});
And the model.cfc under test:
Copy code
component output="false" extends="user" accessors="true" {
    property name="otherUserModel";
    property name="otherMetaData";

    this.otherUserModel = createObject("component", "otherUserModel");

    this.otherMetaData = getComponentMetadata(this.otherUserModel);

    for (variables.p in this.otherMetaData.properties) {
        this[variables.p] = this.otherUserModel[variables.p.name];
    }
    for (variables.f in this.otherMetaData.functions) {
        this[variables.f] = this.otherUserModel[variables.f.name];
    }

    this.otherUserModel.initProps(this);
}
For fuller context, the
otherUserModel
that the above model creates:
Copy code
// OtherUserModel.cfc
component output="false" extends="user" accessors="true" {

    property name="someProp" type="string" getter="true" setter="true";
    // other props...

    public void function initProps(theModel) {
        theModel.setSomeProp("someval");
        // other prop setters etc...
    }

    this.initProps(this);
}
t
oh, yeah, this got me the first time i was doign exception tests too. you need to wrap your call in an anonymous function for it to work.
b
oooo
t
that
() ->
part in my example is important.
1
oh wait... except tht's java isn't it? CF used
=>
?
👍 1
b
yeah so I wrapped it in an arrow function, and now I get a different error: model doesn't exist, but I think it's because I'm using
local.model
. I'm still learning about scoping in CFML, I guess I need to use var model at the outer scope I'm assuming
ok, used
var model = ...
at the top scope in the test
it()
block and it all passes. thank you
reminds me of some things you had to do in react testing library hehe
a
Using testbox to test a component, is there a way to assert that a component has a method?
#QuestionBeggingAlert Why are you thinking this is something you need to test for? What's the test case? eg: "it does x when y"? Method-existence is generally an implementation detail, so not something one would test for
b
I was wondering about that and will probably remove the assertion. For now I am trying to test drive getting a new feature to work in the app so am using tests to verify I've made it over the next hurdle. In this case, I was getting errors about a missing function member in a model (it's unfortunately a kind of weird complicated Frankenstein model I needed to get this feature in place) so I put a test in to check for it and kept reworking things until it passed. As a side note, I struggle with judging what is or is not testing implementation details, but topic for another day - but in this case I agree this is digging too much into the internals of the app.
👍 1