i am testing your code on my dev site and it returns only 1 result (although there are 3 items in the same category), so your code seems to be fine, maybe there is some other filter applied which ignores the posts_per_page param.
You can try using suppress_filters => true
param in your WP_Query args list or use the get_posts() function instead of WP_Query as the function has supress_filters enabled by default so the code would be
$posts = get_posts(array(
'post_type' => 'post',
'category__in' => wp_get_post_categories($post->ID),
'posts_per_page' => 1,
'post__not_in' => array($post->ID)
));
Hope this helps.