I am in the process of writing some tests using testbox. I can do this successfully without using the execute() built in function by mocking out all of my objects. This can quickly become cumbersome because you must “manually” inject properties. I have found out that you can use the execute() function as long as you are extending coldbox.system.testing.BaseTestCase
How would I mock a function while using the execute() method? Code example below
var main= prepareMock( createObject("component","handlers.main") );
var ServiceProvider= PrepareMock( createObject("component","models.example.ServiceProvider"));
var loginUserQuery = querySim("id,username,products
1|example|orderThis");
ServiceProvider.$("loginUserQuery", loginUserQuery);
main.$property(propertyname = "ServiceProvider",mock=ServiceProvider);
var event = execute( event="main.login", renderResults=true );
ServiceProvider does not respect me setting it this way when execute() is called. Are there any other ways I should be mocking the data to get the coldbox framework to respect it?
Thanks in advance for any help!
First, I would do a bit of reading on the difference between an integration test and a unit test. Generally, you do as little mocking as possible in an integration test, because, by definition, an integration test is confirming that the different system components are integrated correctly.
Specifically, if you’re mocking the loginUserQuery()
method, how do you know that the query has the right SQL syntax?
So if you’re feeling the need to mock stuff here, I would question your setup:
- Why do you need to mock the DB? Ask yourself: “Does mocking this introducing a false sense of security?”
- Do you have an isolated test system, preferably in a
docker-compose.yml
file, that you can hit with test code and not worry about affecting production data?
As far as the how, I’m honestly not sure. I don’t usually need to mock methods on a model object inside an integration test (for the reasons I’ve given above).
Thanks Michael for the reply!
I probably should have put the why in my initial post so I apologize for that. I will not have access to the database to be able to test queries fully. You are correct. I will not be able to know if the SQL has the right syntax so this will give me false sense of security.
If you don’t have access to the database, and you can’t create a test database (though I highly recommend it) I would stick to unit tests. You can manually instantiate your handler, inject a mock query service (sorry, ServiceProvider
) and move on with your life without trying to fight the unmockable integration test.
I have found out that you can use the execute() function
If you still want to do integration tests, take a look through Coldbox’s testing guide, it mentions a lot of convenience methods you can find without digging through API docs. Instead of the execute()
method, which is low-level and requires manually specifying a method type, use the get()
, post()
, etc. methods:
Execution of API requests can be done via the convenience request()
method or the HTTP method aliases: get(), post(), put(), patch(), head(), options()
Integration Testing | ColdBox HMVC Documentation
Hope this helps!
Yes this help for sure! I wanted to make sure it was something that I couldn’t do before going down the other route. Thanks again for the tips as they are much appreciated!
1 Like
You’re super welcome! Testing takes real effort at first, but it will pay off sooner than you think. You’re on the right path - good luck!
1 Like