Repository: django/django
File: tests/model_fields/test_jsonfield.py (Python)

Code before:
        obj.refresh_from_db()
        self.assertIsNone(obj.value)

    def test_create(self):
        obj = NullableJSONModel.objects.create(value=JSONNull())
        obj.refresh_from_db()
        self.assertIsNone(obj.value)

    def test_update(self):
        obj = NullableJSONModel.objects.create(value={"key": "value"})
        NullableJSONModel.objects.update(value=JSONNull())
        obj.refresh_from_db()
        self.assertIsNone(obj.value)

    def test_filter(self):
        obj = NullableJSONModel.objects.create(value=JSONNull())
        found = NullableJSONModel.objects.get(value=JSONNull())
        self.assertEqual(obj, found)
        self.assertSequenceEqual(
            NullableJSONModel.objects.exclude(value=JSONNull()), []
        )
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value__isnull=True), []
        )

    def test_case_expression(self):
        with self.subTest("JSONNull() in When.then"):
            obj = NullableJSONModel.objects.create(value={"key": "value"})
            NullableJSONModel.objects.filter(pk=obj.pk).update(
                value=Case(
                    When(value={"key": "value"}, then=JSONNull()),
                )
            )
            obj.refresh_from_db()
            self.assertIsNone(obj.value)
        with self.subTest("JSONNull() in When.condition"):
            obj = NullableJSONModel.objects.create(value=JSONNull())
            NullableJSONModel.objects.filter(pk=obj.pk).update(
                value=Case(
                    When(
                        value=JSONNull(),
                        then=Value({"key": "replaced"}, output_field=JSONField()),
                    )
                ),
            )
            obj.refresh_from_db()
            self.assertEqual(obj.value, {"key": "replaced"})

    def test_key_transform_exact_filter(self):
        obj = NullableJSONModel.objects.create(value={"key": None})
        self.assertSequenceEqual(

Review comment (suggestion):
I think a couple tests with a custom encoder that can serialize `JSONNull` would be good.

Code after:
@skipUnlessDBFeature("supports_primitives_in_json_field")
class JSONNullTests(TestCase):
    def test_repr(self):
        self.assertEqual(repr(JSONNull()), "JSONNull()")

    def test_save_load(self):
        obj = JSONModel(value=JSONNull())
        obj.save()
        self.assertIsNone(obj.value)

    def test_create(self):
        obj = JSONModel.objects.create(value=JSONNull())
        self.assertIsNone(obj.value)

    def test_update(self):
        obj = JSONModel.objects.create(value={"key": "value"})
        JSONModel.objects.update(value=JSONNull())
        obj.refresh_from_db()
        self.assertIsNone(obj.value)

    def test_filter(self):
        json_null = NullableJSONModel.objects.create(value=JSONNull())
        sql_null = NullableJSONModel.objects.create(value=None)
        self.assertSequenceEqual(
            [json_null], NullableJSONModel.objects.filter(value=JSONNull())
        )
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value__isnull=True), [sql_null]
        )

    def test_bulk_update(self):
        obj1 = NullableJSONModel.objects.create(value={"k": "1st"})
        obj2 = NullableJSONModel.objects.create(value={"k": "2nd"})
        obj1.value = JSONNull()
        obj2.value = JSONNull()
        NullableJSONModel.objects.bulk_update([obj1, obj2], fields=["value"])
        self.assertSequenceEqual(
            NullableJSONModel.objects.filter(value=JSONNull()),
            [obj1, obj2],
        )

    def test_case_expression_with_jsonnull_then(self):
        obj = JSONModel.objects.create(value={"key": "value"})
        JSONModel.objects.filter(pk=obj.pk).update(
            value=Case(
                When(value={"key": "value"}, then=JSONNull()),
            )
        )
        obj.refresh_from_db()
        self.assertIsNone(obj.value)