Trying to write a unit test for a service

I am drawing a blank on this one, and just can’t to seem to see if there is any possible way to do it.

The problem is that the service actually requires an event to be passed into the service method to be tested, and I am sure there was a way to get an event in a unit test, but the only way that I can see this is with the execute () which returns an event.

But this would be defeating what I am trying to do if I do an event call before doing the service test.

Anyone have any suggestions?

Also while I am at it, can DI take place in the unit tests, or do we just use normal create object for services?

Regards,

Andrew Scott

http://www.andyscott.id.au/

Mock it!

SUT = new model.service.UserService();
MockBox = new coldbox.system.testing.MockBox();

MockEventObject = MockBox.createStub(‘false’);

MockEventObject.$(‘getCollection’, { foo=‘bar’, username=‘big cows’, … etc … });

result = SUT.doServiceThing(event=MockEventObject);

assertTrue(result, ‘Should have been true baby!’);

Also remember that the base test cases have lots of goodness in them. Try using a base model test case which will give you mocking capabikities already. Also read the bastestcase api you will see all the methods you need.

Luis that is all and good, but none of my questions have been answered.

Again, if I load up a service and it has DI properties will this work?

The answer is no they don’t, when running the service all the DI properties when called report that they are not defined, which means that I am not able to test this, unless there is a special trick one needs to do.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Andrew,

It seems you are misunderstanding the concept of a unit test. Unit tests are tools to isolate a small set of code and test it. That means that dependency injection is not performed and all your dependencies need to be mocked. MockBox is a fantastic solution for this. In your original post on this thread, you mentioned you needed to use an Event Object. Have you tried the mocking code I provided?

You will need to mock all of your dependences to unit test them.

Aaron,

I fully understand Unit Testing, but I rely on DI stuff to manipulate data in my service layer, and frankly I am not going to mock that because how do I know it works?

Yes I did and it works fine, so does the way I was doing it too. But I might end up using the mock when and if I see more valid reasons to do it that way.

Don’t get me wrong here, but you are asking me to mock what I am trying to test works in this case and I must admit I don’t see the validity of mocking something you are trying to test. I will be all ears if you can explain that to me in greater detail.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Unit testing, is where you test the smallest part of your application–a single function for example. You mock all the dependencies so you have no outside influences which lets you simulate a great deal of possibilities. I have found this type of testing to be invaluable–especially, when done in addition to integration testing. The reason one chooses to mock the dependencies their service depends on is so they know, during these tests, with absolute certainty what values/data those dependencies are providing to your function under test. In this way, you can guarantee your function should return the expected result. For example, if you have a “RegisterUser” function that depends on a DAO to save a user using your ORM stuff, when you are testing RegisterUser you may mock the behavior of the DAO so it always returns “TRUE - I saved the user” to allow you to test that your RegisterUser function will send an e-mail when the user is properly registered; however, another test of the ResgisterUser function may mock the DAO result as “FALSE - Here are three errors that stopped me from saving”. Now, you can properly test how your RegisterUser function reacts to that condition. You are only testing the RegisterUser function.

Integration testing is where you test your handler and the most of the normal ColdBox request-cycle still occurs including dependency injection. I choose to use both Unit Testing and Integration testing.

When I am writing a Service Method, I also write the unit test–mocking all of the dependencies and input. When I write an Event Handler, I write the integration tests (in that order).

Aaron I did say I understand that, I do mocking for my ORM stuff now. But I end up removing it because I haven’t worked out how to mock constraint errors.

The problem I have is that one of my service layers has a plugin DI’ed into the service I am writing the test for, the problem is that I can’t mock the data for this. Well I can but I don’t see how it is possible, because it is the AntiSammy plugin. I might be thinking in the wrong direction and that is fine, I am still open to mocking, just need more information I guess.

For example I am trying to unit test an interceptor, the interceptor requires certain information to be available in the requestContext. I am not able to get this working, in anyway shape or form.

The error that I am getting is something along the lines of, Expression: Element CONTEXT is undefined in INSTANCE.

So not sure what I am doing wrong there.

Regards,

Andrew Scott

http://www.andyscott.id.au/

Please post your interceptor, the test and an explanation of the desired behavior.

Hey Everyone,

I’m trying to figure out how to do some simple pagination using a VirtualEntityService.

in BaseORMService, findAll has the offset/max as arguments. But, VirtualEntityService’s findAll doesn’t.

Does anyone have any best practices for accomplishing basic page sets using a VirtualEntityService?

Thanks!
Ben

Hi Aaron thanks but I got it working, the problem was I was using

Interceptor.contextAppend(context);

When I should have been doing

Interceptor.$property(‘context’,’instance’, context);

Regards,

Andrew Scott

http://www.andyscott.id.au/