I recommend that you do not do it that way.
If the data of the source layer does not change frequently, it would be best to dissolve the features of the original layer by creating a new layer; style that layer and move on. This is the best solution in terms of rendering speed.
If the shapes of the polygons or the value of the grouping field usually change, then a little performance can be sacrificed in order to have a virtual layer, wich is updated immediately every time a modification in some of the original features is produced. Again, apply the style to the virtual layer. After that, be careful not to change the name of the original layer or grouping field.
But let's go into detail about the idea of styling a layer aggregating geometries with the geometry generator:
The collect function aggregates, in this case, the geometries of all the features of the layer, grouping them by the value of the feature attribute in a field. This grouping does not mean that it dissolves the geometries, but that it generates a multi-part geometry for each group, in which each part is one of the original geometries.
Assigning this expression in the geometry generator, the expression is evaluated once for each feature that must be rendered on the canvas, each time the canvas is refreshed. This means that if the original layer has 100 features, and you fully zoom the layer, 100 aggregates of 100 features each must be computed on the fly, rendered one on top of the other.
Both exterior_ring and boundary functions need a single-part geometry as input. Since collect is returning a multi-part geometry, both functions return always NULL.
Also, exterior_ring and boundary functions return a LineString type geometry, so you need indicate it to the geometry generator, assigning the appropriate value in the Geometry type menu.
You don't need that functions anyway. If you had the dissolved polygon, you can assign a fill style with the Fill style: No Brush, and only the polygon rings would be displayed.
The trick of causing the parts of each group to dissolve, is usually to apply a buffer of radius 0 to the group, with the following expression: buffer( collect( $geometry, group_by:= 'nom_dept'), 0). This adds considerable time to rendering processing.
In the case of non-topological geometries (spaghetti geometries in the GRASS terminology), if all vertices are not shared by all adjacent polygons, coordinate rounding can cause two parts not to dissolve using a radius 0 in the buffer. The trick to force dissolution is to add two buffers instead of one: a small buffer out and one inwards. This can be achieved with the following expression: buffer( collect( buffer( $geometry, 0.1), group_by:= 'nom_dept'), -0.1). In addition to doubling the rendering time (with 100 original features you should sit back and wait for the canvas to refresh every time you make pan or zoom), invalid geometries (by overlapping parts) are being produced in the intermediate step. It is likely that QGIS will crash before finishing rendering.
The Geometry Generator seems to me a powerful tool. The aggregate functions included in the Expression Builder as well. But it doesn't seem advisable to aggregate geometries in the geometry generator of the layer style.