docs: add TransactionCase commit safety and mock call inspection patterns to CLAUDE.md

This commit is contained in:
Nicholas Riegel 2026-05-30 00:20:29 -04:00
parent 483d8530fe
commit f26f896fe4

View file

@ -130,6 +130,12 @@ class TestSaleOrderDiscount(TransactionCase):
- `setUp` / inline: test-specific data (partners, orders, invoices). - `setUp` / inline: test-specific data (partners, orders, invoices).
- Do **not** create shared mutable state; each test must be independent. - Do **not** create shared mutable state; each test must be independent.
**Critical: Never call `self.env.cr.commit()` in code being tested by TransactionCase**
- TransactionCase uses database savepoints; each test gets rolled back automatically
- `commit()` breaks the savepoint chain, causing `InFailedSqlTransaction` errors in subsequent tests
- **Use `self.env.flush_all()` instead** to persist changes while keeping the test isolated
- If you need to test explicit commits, use `TestCase` instead (slower, no auto-rollback)
### 3.2 HttpCase (use rarely — only for controllers or UI tours) ### 3.2 HttpCase (use rarely — only for controllers or UI tours)
```python ```python
@ -792,6 +798,8 @@ post = self.env['blog.post'].sudo().create({
| Mail test: `mail.mail.subject` is `False` instead of string | Template subject field not rendered by send_mail() | Verify template fields are populated in DB; render manually if needed | | Mail test: `mail.mail.subject` is `False` instead of string | Template subject field not rendered by send_mail() | Verify template fields are populated in DB; render manually if needed |
| Odoo 17: `blog.post` doesn't accept `body` or `body_arch` fields | Fields renamed/removed in Odoo 17 | Use factory pattern with `.sudo().create()` to bypass validation; post content should be managed via editor interface, not direct assignment | | Odoo 17: `blog.post` doesn't accept `body` or `body_arch` fields | Fields renamed/removed in Odoo 17 | Use factory pattern with `.sudo().create()` to bypass validation; post content should be managed via editor interface, not direct assignment |
| Odoo 17: Inverse relationship not loaded in template context | Relations lazy-load; mail.template context may not include reverse relations | Use explicit search in Mako (`for loop`) instead of relying on inverse field; or fetch record with prefetch in the render context | | Odoo 17: Inverse relationship not loaded in template context | Relations lazy-load; mail.template context may not include reverse relations | Use explicit search in Mako (`for loop`) instead of relying on inverse field; or fetch record with prefetch in the render context |
| Test: `IndexError: tuple index out of range` when accessing `mock.call_args[0][0]` | Mock method called with keyword-only args; `call_args[0]` is empty tuple `()` | Use `mock.call_args[1].get('key')` for kwargs; or check `mock.called` before accessing `call_args` |
| Test: TransactionCase gets `InFailedSqlTransaction` in subsequent tests | Previous test called `self.env.cr.commit()` breaking savepoint chain | Replace `commit()` with `flush_all()` in code being tested; `commit()` is only allowed in non-test code in production |
--- ---