diff --git a/swh/model/hypothesis_strategies.py b/swh/model/hypothesis_strategies.py
index 2dc601b1b26116f2f9879f4eea95afa511aebfd7..320b160b4193cd01dc3ab159b87b11d417aa59f3 100644
--- a/swh/model/hypothesis_strategies.py
+++ b/swh/model/hypothesis_strategies.py
@@ -315,13 +315,16 @@ def snapshots_d(draw, *, min_size=0, max_size=100, only_objects=False):
     if not only_objects:
         # Make sure aliases point to actual branches
         unresolved_aliases = {
-            target['target']
-            for target in branches.values()
+            branch: target['target']
+            for branch, target in branches.items()
             if (target
                 and target['target_type'] == 'alias'
                 and target['target'] not in branches)
-         }
-        for alias in unresolved_aliases:
+        }
+        for alias_name, alias_target in unresolved_aliases.items():
+            # Override alias branch with one pointing to a real object
+            # if max_size constraint is reached
+            alias = alias_target if len(branches) < max_size else alias_name
             branches[alias] = draw(branch_targets_d(only_objects=True))
 
     # Ensure no cycles between aliases
@@ -343,7 +346,8 @@ def snapshots_d(draw, *, min_size=0, max_size=100, only_objects=False):
 
 
 def snapshots(*, min_size=0, max_size=100, only_objects=False):
-    return snapshots_d(min_size=0, max_size=100, only_objects=False).map(
+    return snapshots_d(min_size=min_size, max_size=max_size,
+                       only_objects=only_objects).map(
         Snapshot.from_dict)
 
 
diff --git a/swh/model/tests/test_hypothesis_strategies.py b/swh/model/tests/test_hypothesis_strategies.py
index dd77c8de4e6c742233ade4d8617704b04bb22d41..76011843c6484bcd49605750179cf72510325d6b 100644
--- a/swh/model/tests/test_hypothesis_strategies.py
+++ b/swh/model/tests/test_hypothesis_strategies.py
@@ -6,10 +6,13 @@
 import datetime
 
 import attr
-from hypothesis import given
+from hypothesis import given, settings
 
 from swh.model.hashutil import DEFAULT_ALGORITHMS
-from swh.model.hypothesis_strategies import objects, object_dicts
+from swh.model.hypothesis_strategies import (
+    objects, object_dicts, snapshots
+)
+from swh.model.model import TargetType
 
 
 target_types = (
@@ -80,3 +83,42 @@ def test_model_to_dicts(obj_type_and_obj):
     elif obj_type == 'snapshot':
         for branch in obj_dict['branches'].values():
             assert branch is None or branch['target_type'] in target_types
+
+
+_min_snp_size = 10
+_max_snp_size = 100
+
+
+@given(snapshots(min_size=_min_snp_size, max_size=_max_snp_size))
+@settings(max_examples=1)
+def test_snapshots_strategy(snapshot):
+
+    branches = snapshot.branches
+
+    assert len(branches) >= _min_snp_size
+    assert len(branches) <= _max_snp_size
+
+    aliases = []
+
+    # check snapshot integrity
+    for name, branch in branches.items():
+        assert branch is None or branch.target_type.value in target_types
+        if branch is not None and branch.target_type == TargetType.ALIAS:
+            aliases.append(name)
+            assert branch.target in branches
+
+    # check no cycles between aliases
+    for alias in aliases:
+        processed_alias = set()
+        current_alias = alias
+        while (branches[current_alias] is not None
+                and branches[current_alias].target_type == TargetType.ALIAS):
+            assert branches[current_alias].target not in processed_alias
+            processed_alias.add(current_alias)
+            current_alias = branches[current_alias].target
+
+
+@given(snapshots(min_size=_min_snp_size, max_size=_min_snp_size))
+@settings(max_examples=1)
+def test_snapshots_strategy_fixed_size(snapshot):
+    assert len(snapshot.branches) == _min_snp_size