Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NS3002 false positive when nested returns #150

Closed
andrewdmoreno opened this issue Nov 20, 2020 · 6 comments · Fixed by #151
Closed

NS3002 false positive when nested returns #150

andrewdmoreno opened this issue Nov 20, 2020 · 6 comments · Fixed by #151
Milestone

Comments

@andrewdmoreno
Copy link

#118 was closed so did not want to add onto it, however, I am running into this issue still.

var provider = Substitute.For<IOptionProvider>();

provider
    .GetOptions(Arg.Any<EnrollmentDetail>())
    .Returns(_ =>
        {
            //  NS3002 Can not find an argument of type ... to this call
            var enrollment = _.Arg<EnrollmentDetail>();
            return new List<OptionSummary>();
       });

IOptionProvider:

List<OptionSummary> GetOptions(EnrollmentDetail enrollment);

I tried with versions 1.0.11, 1.0.13, and 1.0.14. Am I doing something wrong possibly?

@tpodolak
Copy link
Member

tpodolak commented Nov 21, 2020

Hi @andrewdmoreno
I am not able to repro this. Here is my code based on your snippet

using System.Collections.Generic;
using NSubstitute;

namespace TestProject6
{
    public class FooTests
    {
        public void Test()
        {
            var provider = Substitute.For<IOptionProvider>();

            provider
                .GetOptions(Arg.Any<EnrollmentDetail>())
                .Returns(_ =>
                {
                    var enrollment = _.Arg<EnrollmentDetail>();
                    return new List<OptionSummary>();
                });
        }
    }

    public interface IOptionProvider
    {
        List<OptionSummary> GetOptions(EnrollmentDetail enrollment);
    }

    public class OptionSummary
    {
    }

    public class EnrollmentDetail
    {
    }
}

no warnings were reported with

<PackageReference Include="NSubstitute" Version="4.2.1" />
<PackageReference Include="NSubstitute.Analyzers.CSharp" Version="1.0.14" />

Can you provide small solution with repro?

@andrewdmoreno
Copy link
Author

Thanks @tpodolak. I will double check both package versions and see if I can repro it in a smaller solution.

@andrewdmoreno
Copy link
Author

andrewdmoreno commented Nov 22, 2020

@tpodolak At first I could not repro in a fresh solution so I started looking at what else was unique about the setup and was finally able to repro. I reduced it down to the minimum needed to repro. Basically it was only when I introduced the IProviderFactory substitution setup was I able to repro.

    public class FooTests
    {
        public void Test()
        {
            var providerFactory = Substitute.For<IProviderFactory>();
            providerFactory.GetProvider().Returns(info =>
            {
                var provider = Substitute.For<IOptionProvider>();
                provider
                    .GetOptions(Arg.Any<string>())
                    .Returns(_ =>
                    {
                        // Warning	NS3002	Can not find an argument of type string to this call.
                        var input = _.Arg<string>();
                        return new List<string> {input};
                    });
                return provider;
            });
        }
    }

    public interface IProviderFactory
    {
        IOptionProvider GetProvider();
    }

    public interface IOptionProvider
    {
        List<string> GetOptions(string input);
    }

@dtchepak
Copy link
Member

@andrewdmoreno Thanks for taking the time to refine the reproduction case!

@tpodolak I'm guessing the issue is the nested Returns here?

@andrewdmoreno andrewdmoreno changed the title NS3002 false positive (still occurring) NS3002 false positive when nested returns Nov 23, 2020
@andrewdmoreno
Copy link
Author

Now that we know that the nested Returns caused this false positive I have mitigated the issue on my end by moving the provider setup outside and just returning the provider instance like so:

    public class FooTests
    {
        public void Test()
        {
            var provider = Substitute.For<IOptionProvider>();
            provider
                .GetOptions(Arg.Any<string>())
                .Returns(_ =>
                {
                    var input = _.Arg<string>();
                    return new List<string> {input};
                });

            var providerFactory = Substitute.For<IProviderFactory>();
            providerFactory.GetProvider().Returns(provider);
        }
    }

    public interface IProviderFactory
    {
        IOptionProvider GetProvider();
    }

    public interface IOptionProvider
    {
        List<string> GetOptions(string input);
    }

However, I imagine there could be valid use cases for having nested Returns

@tpodolak
Copy link
Member

tpodolak commented Nov 23, 2020

@tpodolak I'm guessing the issue is the nested Returns here?

@dtchepak yes, there is a missing check if given Arg<T> belongs to given callInfo parameter.

@tpodolak tpodolak added this to the 1.0.15 milestone Nov 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants