`Map` (`/@`) returns the results of the iterations of `AssociateTo` in a list and that is confusing you. You can suppress the output by using `Scan` instead of `Map`. Actually, the output of the mapped function is not of interest to you. What matters is the value of `test` afterwards, as `AssociateTo` uses call by reference.
test = Association[{a -> 1, b -> 2, c -> 3}]
Scan[
(If[MissingQ[test[#]],
AssociateTo[test, # -> 1],
AssociateTo[test, # -> (test[#] + 1)]
]) &,
{a, b, c, d, e}
];
test
> <|a -> 1, b -> 2, c -> 3|>
>
> <|a -> 2, b -> 3, c -> 4, d -> 1, e -> 1|>
Using `Scan` instead of `Map` increases performance since for returning the intermediate results of `AssociateTo` requires copying them. But that is what you actually try to avoid by using `AssociateTo` instead of using `Associate` recursively.
Here is an illustration of the performance difference:
n = 100000;
a = b = AssociationThread[Range[n], RandomInteger[10, n]];
rand = RandomInteger[n, n];
a == b
Scan[
(If[MissingQ[a[#]],
AssociateTo[a, # -> 1],
AssociateTo[a, # -> (a[#] + 1)]
]) &,
rand
]; // AbsoluteTiming //First
Map[
(If[MissingQ[b[#]],
AssociateTo[b, # -> 1],
AssociateTo[b, # -> (b[#] + 1)]
]) &,
rand
]; // AbsoluteTiming //First
a == b
> 0.30575
>
> 0.517976
>
> True