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

SetupSequence does not work when returning null first #1003

Closed
tfierens opened this issue Apr 20, 2020 · 5 comments
Closed

SetupSequence does not work when returning null first #1003

tfierens opened this issue Apr 20, 2020 · 5 comments
Labels

Comments

@tfierens
Copy link

tfierens commented Apr 20, 2020

Hi,

I think I just spotted a bug when using the SetupSequence when trying to return is null first.

For example:

        var nullCompany = (Company)null;
        var emptyCompany = new Company{Id = 1};

        myService.SetupSequence(s => s.Companies.Get(1))
                  .Returns(nullCompany)
                  .Returns(emptyCompany);

When calling Companies.Get(1), it returns null and when calling it the second time, it also returns null but if you swap the values around for the return

        myService.SetupSequence(s => s.Companies.Get(1))
                  .Returns(emptyCompany)
                  .Returns(nullCompany);

It will work as expected and return the empty company and then the null value.

I've tried it using a single .Return with an Queue, same thing. tried to call a function instead for each .Return definition just to try different things, but the behaviour is the same for everything I've tried.

This is happening with version: 4.10.0.0 using .NET 2017.

Any workaround would be great.

Thanks

@stakx
Copy link
Contributor

stakx commented Apr 21, 2020

I cannot reproduce what you're describing. Can you please provide minimal but complete repro code? (Also, please test with the latest version of Moq, since that is the only one we're working on.)

Here's a working counterexample:

public interface ICollection<T>
{
    T Get(int id);
}

public class Company
{
    public Company(int id)
    {
        this.Id = id;
    }

    public int Id { get; }
}

public interface IEvilLord
{
    ICollection<Company> Companies { get; }
}

[Fact]
public void Test()
{
    var nullCompany = (Company)null;
    var emptyCompany = new Company(1);
    var mock = new Mock<IEvilLord>();

    mock.SetupSequence(m => m.Companies.Get(1))
        .Returns(nullCompany)
        .Returns(emptyCompany);

    Assert.Null(mock.Object.Companies.Get(1));
    Assert.Same(emptyCompany, mock.Object.Companies.Get(1));
}

@tfierens
Copy link
Author

@stakx Thanks for the prompt reply.

You were right, even with the version I'm working with, it worked as expected. I got fixated on a specific chunk of code and missed an additional call being made to the function so it looks like it wen from null, object, null thus making me think it was return null, null when starting with null.

I would have thought it would have thrown an error of some sort if called too many times but it either is returning null or cycling back up through the sequence.

I'm not sure but at least it is not a bug as I originally thought and I can continue with my work.

Apologies & thanks.

Thierry

@tfierens
Copy link
Author

Not a bug so closing

@tfierens
Copy link
Author

Might have spoken too quickly but will keep investigating.

@stakx
Copy link
Contributor

stakx commented Apr 21, 2020

I would have thought it would have thrown an error of some sort if called too many times but it either is returning null or cycling back up through the sequence.

At least for a loose mock, that's the expected behavior. For calls that either don't match a setup, or match a setup that has no return value configured, a default value (as per your mock.DefaultValue and mock.SetReturnsDefault settings) gets returned. So once a sequential setup is "exhausted", it's basically a setup with no return value configuration.

@stakx stakx added invalid and removed needs-repro labels Apr 21, 2020
@devlooped devlooped locked and limited conversation to collaborators Sep 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants