Testing with RSpec, Factory Girl & default_scope multi-tenancy

I’m trying to get started with TDD but I’m struggling with the combination of multi-tenancy using default_scope, Devise for authentication and Factory Girl factories.

Most of the ‘getting started’ guides I see simply use association: whatever in the factory to build random parent/related objects but when those objects are the tenant I need it to be more controlled.

My model tests are ok because they’re isolated but as soon as I try to test any kind of integration I can’t control the tenants without writing lots of code in the test.

I should point out that my app is live and is currently tested manually (gulp!) so I’m not able to make sweeping changes like switching to schema-based multi-tenancy etc.

Tenant: School
Users: Teacher, Student
Thing: Lesson

All teachers and students belong_to a school. All students are assigned to teachers through classes. All lessons are created by teachers and belong_to students.

I realize this is a massively broad question but I’d be grateful of any resources or guides for how I should proceed testing this particular setup.

First of all, I discourage folks from using schema-based multi tenancy – as does Ryan Biggs who’s a pretty good expert on the subject (His book Multitenancy with Rails is one of the best resources) So you’re seemingly in good shape there. Since it’s pretty clear you’re using scope-based multitenancy which should make testing easier.

However, as you admit, the question is pretty broad, so could you perhaps share some code or at least a description of a particular test you’re trying to write? I think then we might be able to provide some more clarity. Sorry about the non-answer, but basically I think we (or at least I) need a little more information to be helpful.

If you need lots of code to setup the tests then you need lots of code. Your integration tests are also going to be somewhat longer than unit tests since they’re testing a larger area of your application.

Someone else might have a better idea but I’d probably start by writing an integration test including all the setup (even if that’s 10–15 lines), then start writing the second test and extract out of the first, any setup that’s common between the two (authentication, creating the user / school relationship).

Devise also has a section on testing that includes information on the helpers you’ll need to bypass the authentication logic (I’d guess you’ll be testing access-approved and access-denied states but not the authentication logic actually provided by Devise).

Hope some of that’s helpful.

@briandear Thanks for the tip on multi tenancy. I am definitely happy with the scope-based system I’m using, it can get in the way a lot in the console but on the whole I like it. I bought Ryan’s book and I’ve worked through a lot of it but it has an extra layer of complication where he builds the multi tenant system into a gem, which feels to me like it gets in the way of the main thrust of the book.

@chrisradford That sounds like good advice. I started with model tests but as soon as I started to write controller tests I realized I was going to need a lot of setup for each action so I decided to skip straight on to integration tests. Extracting out the common setup is basically the way I’ve gone. I’m still scratching my head a bit with before and let and it took me a moment to understand that local variables in a before block don’t pass through to the scenario. That’s how new I am to testing, and programming in general!

I’ll be sure to take a good look at the Devise advice on testing since that’s the point of entry for most tests as this app doesn’t have any anonymous/public access at all apart from the landing page (sign up) page.

When I hit a concrete example of a problem I’m having in the tests I’ll post actual code as @briandear suggests. Apologies for the vast scope of this question. I’ll ask more refined questions in the future :smile: