Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions template/module/models/abstract_something.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# -*- coding: utf-8 -*-
# Copyright <YEAR(S)> <AUTHOR(S)>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from openerp import models


class AbstractSomething(models.AbstractModel):
_name = "abstract.something"
_description = "Abstract Somethings"
1 change: 1 addition & 0 deletions template/module/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from . import test_something
from . import test_abstract_something
53 changes: 53 additions & 0 deletions template/module/tests/test_abstract_something.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
# Copyright <YEAR(S)> <AUTHOR(S)>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from openerp import api, models
from openerp.tests.common import SingleTransactionCase


class AbstractSomethingTester(models.Model):
""" It provides a real model object to test the abstract with """
_name = 'abstract.something.tester'
_description = 'Abstract Something Tester'
_inherit = 'abstract.something'


class TestAbstractSomething(SingleTransactionCase):
@classmethod
def _init_test_model(cls, model_cls):
""" It builds a model from model_cls in order to test abstract models

Args:
model_cls: (openerp.models.BaseModel) Class of model to initialize
Returns:
Model instance
"""
model_cls._build_model(cls.registry, cls.cr)
model = cls.env[model_cls._name].with_context(todo=[])
model._prepare_setup()
model._setup_base(partial=False)
model._setup_fields(partial=False)
model._setup_complete()
model._auto_init()
Copy link
Contributor

@obulkin obulkin Dec 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the method that actually creates a table for the model, and it will break the isolation provided by TransactionCase: https://github.com/odoo/odoo/blob/18456b9d42769a522adf86183746b49735e9d8b3/odoo/models.py#L2535. Unfortunately, I don't see a way to proceed beyond the _setup_complete() step without introducing this issue, and doing so seems to defeat the entire purpose of building a model in this way, so the last few calls here should probably be dropped.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm yep good call, thanks @obulkin. I can't think of an instance where the table be required outside of the test transaction, so I believe you're correct in being able to remove it. Well, that and the whole necessity thing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep I've forgotten to mock cr.commit...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ohhhh mock cr.commit! And there's the solution, I like this better than removing the table creation. Thanks @lmignon

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TIL, thanks @yajo. So glad I made this PR, we're really drilling to the true solution!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh. Nice find, @yajo. I wonder why TransactionCase doesn't just use the test cursor/savepoint approach.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't so nice at the beginning, it's just getting nicer now. 😆

FTR, TransactionCase makes a rollback instead. Not sure why, but that's what it does.

model.init()
model._auto_end()
return model

@classmethod
def setUpClass(cls):
super(TestAbstractSomething, cls).setUpClass()
cls.registry.enter_test_mode()
cls.old_cursor = cls.cr
cls.cr = cls.registry.cursor()
cls.env = api.Environment(cls.cr, cls.uid, {})
cls.test_model = cls._init_test_model(AbstractSomethingTester)

@classmethod
def tearDownClass(cls):
cls.registry.leave_test_mode()
cls.registry[cls.test_model._name]._abstract = True
cls.registry[cls.test_model._name]._auto = False
cls.cr = cls.old_cursor
cls.env = api.Environment(cls.cr, cls.uid, {})
super(TestAbstractSomething, cls).tearDownClass()