Engines: How to write tests that depend upon main app models?

Hello all.

The Rails Engines documentation1 was really quite good for understanding how to write engines. However, it left me with a question which I’ve been unable to answer.

Say I’m writing the engine discussed in the documentation (a blog). The Post model doesn’t need to know anything about its author, and this engine doesn’t need to deal with accounts in any way, but it makes sense for posts to have an author, so we make the class for the author configurable and we say that the Post model belongs_to it. The engine can then simply make use of whatever account scheme is in use in the main application.

How then do we write tests for the Post model if the engine doesn’t contain a model for the author? I’m using FactoryGirl and I tried just putting together a factory for a user, but it doesn’t work without a corresponding table. I suppose I could create a basic Author class within the generated test/dummy application, but then all the tests would have to be put in there as well, which feels a little nasty to me (I just want my tests in an obvious place, I guess). I think a solution is probably outside of the testing setup being used (rspec, minitest, fixtures or factories, etc.).

I feel like this is a fairly typical use for an engine, so I thought maybe some of you had run into this issue before. I appreciate any help!

I’ve done this by just adding my author class equivalent in test/dummy. You don’t have to also put the tests in there though

Fred

Hi Kyle and Frederick,

I have a point of view I would like to share.

I have developed an application in rails for the 1 year and a half with more than 6 different engines. He have been through this problem too many times and our conclusion was very simple. We had to create a Core engine where he had all the shared code but also almost all our models. There was a lot of reasons for doing so:

  1. Almost all our models have relations in between them, so they should not be separate in different engines, they will always depend on each other. applying this to your example: If there is an author on blog, most likely there will be some methods inside that blog that will use the author for something.

  2. Then Core will act like a gem, where all the other engines that should have separate and independent code, will just install. So your blog engine will always be dependent on the core gem, but its such a basic dependency as we all depend on Active Record.

  3. The tests will be simple and easier to do. The solution presented by Frederick is not so good as: 1. Your dummy app will be dependent on having a class called author, so should be every other app that uses your engine. So what’s the point on doing a engine if they will have dependencies in between them? 2. You should never commit the dummy app code.

Maybe this is not the most correct approach to your problem. But its an idea you can use.

Just one more comment. I can see you have written this in your problem: “The engine can then simply make use of whatever account scheme is in use in the main application.”, this is almost impossible to achieve, because you dont know what the author is. You either pretend there is no author at all and the main app developer decides what to call and what to you use. Or you give 1,2 or 3 different alternatives.