Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use multiple datasources in testing #4694

Closed
trichins opened this issue Sep 22, 2014 · 12 comments
Closed

Unable to use multiple datasources in testing #4694

trichins opened this issue Sep 22, 2014 · 12 comments

Comments

@trichins
Copy link
Contributor

I have multiple datasources set up in Config/database.php and they each have a test version. Some examples are:

default
test
FileSource
test_FileSource
IniSource
test_IniSource

The models are using their correct datasource and they work fine. In my test fixtures, I have each of the fixtures importing in their corresponding model (public $import = 'ModelName') and using the corresponding test datasource (public $useDbConfig = 'test_source'). I believe that is what book.cakephp.org/2.0/en/development/testing.html says I should do.

But it doesn't work. I get a "MissingTableException" in Model::setSource() because it is always using the "test" datasource.

I'm not sure the best way to fix it but for now, I've overwritten CakeTestCase::getMockForModel and call "ClassRegistry::config('Model', array('ds' => null))" before calling the parent getMockForModel. I think call setDataSource myself using the information from useDbConfig.

@dereuromark dereuromark added this to the 2.5.5 milestone Sep 22, 2014
@markstory
Copy link
Member

So you are importing the schema from the non-test models?

@trichins
Copy link
Contributor Author

Yes

@markstory
Copy link
Member

And how is getMockForModel() getting involved?

@markstory
Copy link
Member

You cannot use alternate datasources with the string form of import. You must use the array form:

public $import = array('model' => 'Paste', 'connection' => 'two');

The existing section in the docs covers this. If there is something that could be added to the docs to make the limitations of the string form more clear let me know, I'm happy to update the docs.

@trichins
Copy link
Contributor Author

That doesn't work. From the docs, that is talking about importing the table definition. My models in the other datasources have their table definition defined inside of them.

And the docs say that what I'm doing should work. If you read the paragraph that starts with "The $useDbConfig property defines the datasource of which the fixture will use." you'll see that it says that I just need to make sure that the datasource starts with "test_" and it will work. That is not happening.

getMockForModel is used to generate the model. I need to mock out a few things in the model so I'm using that. I found that the change in 46b28aa caused this problem. Before, I could pass in a null config and it wouldn't use the default config (which has 'test' always set as the 'ds'). Now, I have to clear out ClassRegistry::config('Model') to prevent that.

@markstory
Copy link
Member

The example I posted worked for me last night. I was able to import schema from two different data sources.

The $useDbConfig property defines which connection the fixture will insert its schema and data into. I can double check that my schema and data were going into their respective connections, but reading schema from multiple datasources did work for me.

@markstory markstory reopened this Sep 23, 2014
@markstory markstory removed the defect label Sep 23, 2014
@trichins
Copy link
Contributor Author

Yes, I have different test datasources. One is in postgres, another is a file. I don't just want to use the "test" datasource but I also want to use the "test_FileSource" datasource as well.

I've created a basic app that just has my model, datasource, fixture, and test case and I can duplicate it. Is there a way to attach a zip to this issue?

@markstory
Copy link
Member

Putting the relevant files into a gist is probably the best option.

@trichins
Copy link
Contributor Author

The gist is over at https://gist.github.com/trichins/1b538db7aba161f51467.

@markstory
Copy link
Member

Thanks 👍

@markstory markstory self-assigned this Sep 23, 2014
@markstory markstory modified the milestones: 2.5.5, 2.5.6 Oct 5, 2014
@markstory
Copy link
Member

So I finally had some more time to look into this, and from what I can see the issue only crops up when getMockForModel() is used. When using ClassRegistry::init() the correct connection names are used.

I figured out the issue and will have a pull request up shortly.

markstory added a commit that referenced this issue Oct 13, 2014
Because getMockForModel() does not go through the test datasource
injection in ClassRegistry::init() we need to duplicate the basics of
that logic here. Thankfully, we already have a mock so we can do that
datasource switching without reflection. Of course this means there will
be limitations to how/when this will work, but I feel those scenarios
can probably be solved by not using mocks, or by mocking out the
problematic methods. This set of changes makes getMockForModel() work
with secondary datasources, as one would expect it to do, but I'm not
sure it ever did.

Refs #4694
@markstory
Copy link
Member

Closing as a pull request is up now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants