简体   繁体   English

为什么此NSubstitute收到呼叫失败?

[英]Why does this NSubstitute Received Call Fail?

Test in question: "TestGetAllPeople()" 有问题的测试:“ TestGetAllPeople()”

I was experimenting with Unit testing frameworks (as I don't have a lot of experience using them) and I'm encountering an error I cant see to suss out. 我正在尝试使用单元测试框架(因为我没有太多使用它们的经验),并且遇到一个我看不出来的错误。

According to the documentation ( https://nsubstitute.github.io/help/received-calls/ ) (I believe). 根据文档( https://nsubstitute.github.io/help/received-calls/ )(我相信)。 It shouldn't fail, because I ran it through the debugger and it IS called, it retrieves the two people so there is something I'm obviously missing. 它不应该失败,因为我通过调试器运行了它,并且调用了它,它检索了两个人,因此显然我缺少了一些东西。

  • VS2015, VS2015,
  • .NET 4.5.2, .NET 4.5.2,
  • NSubstitute 3.1, N替代3.1,
  • NUnit 3.9 and NUnit 3.9和
  • NUnitAdapter 3.9. NUnitAdapter 3.9。

Person.cs Person.cs

public interface IPersonRepository
{
    List<Person> GetPeople();
    Person GetPersonByID(string ID);
}

public class Person
{
    public string ID;
    public string FirstName;
    public string LastName;

    public Person(string newID, string fn, string ln)
    {
        ID = newID;
        FirstName = fn;
        LastName = ln;
    }
}

public class PersonService
{
    private IPersonRepository personRepo;

    public PersonService(IPersonRepository repo)
    {
        personRepo = repo;
    }

    public List<Person> GetAllPeople()
    {
        return personRepo.GetPeople();
    }

    public List<Person> GetAllPeopleSorted()
    {
        List<Person> people = personRepo.GetPeople();
        people.Sort(delegate (Person lhp, Person rhp)
        {
            return lhp.LastName.CompareTo(rhp.LastName);
        });
        return people;
    }

    public Person GetPerson(string ID)
    {
        try
        {
            return personRepo.GetPersonByID(ID);
        }
        catch(ArgumentException)
        {
            return null; // No person found
        }
    }
}

Tests 测试

[TestFixture]
public class Tests
{

    //This is our mock object
    private IPersonRepository personRepoMock;

    //Data
    private Person personOne = new Person("1", "A", "Test");
    private Person personTwo = new Person("2", "B", "Yest");
    private List<Person> peopleList;

    [SetUp]
    public void TestInit()
    {
        //For lauching VS debugger
        //System.Diagnostics.Debugger.Launch();

        peopleList = new List<Person>();
        peopleList.AddRange(new Person[] { personOne, personTwo });

        //Mock/Fake object of IPersonRepository
        personRepoMock = Substitute.For<IPersonRepository>();


        //FAKES --------------------------------------------
        //Remember Subtitute.ForPartsOf!
        //https://nsubstitute.github.io/help/partial-subs/
    }

    [TearDown]
    public void TearDown()
    {
        //TODO
    }

    [Test]
    public void CanCreate()
    {
        Person person = new Person("1", "A", "Test");
        Assert.IsNotNull(person);
    }

    [Test]
    public void TestGetAllPeople()
    {
        //Expects a call to GetPeople and returns peopleList
        //Weirdly enough the call IS receieved as it DOES return the people list
        //Through the mock, but throws saying it wasnt
        personRepoMock.Received().GetPeople().Returns(peopleList);

        //-------------Expectations-------------
        //Checking for multiple received 
        //personRepoMock.Received(x).etc
        //Clearing
        //personRepoMock.ClearReceivedCalls();
        //-------------Expectations-------------

        //Using this version to continue development for now.
        //personRepoMock.GetPeople().Returns(peopleList);
        PersonService pServ = new PersonService(personRepoMock);
        Assert.AreEqual(2, pServ.GetAllPeople().Count);
    }

    [Test]
    public void TestGetAllPeopleSorted()
    {
        //Expectss a call to get people and returns a peopleList
        //personRepoMock.Received().GetPeople().Returns(peopleList);
        personRepoMock.GetPeople().Returns(peopleList);

        PersonService pServ = new PersonService(personRepoMock);

        List<Person> people = pServ.GetAllPeopleSorted();
        Assert.NotNull(people);
        Assert.AreEqual(2, people.Count);
        Person p = people[0];
        Assert.AreEqual("Test", p.LastName);
    }

    [Test]
    public void TestGetSinglePersonWithValidID()
    {
        //Expectss a call to GetPerson and returns personOne
        personRepoMock.GetPersonByID(Arg.Is("1")).Returns(personOne);

        PersonService pServ = new PersonService(personRepoMock);

        Person p = pServ.GetPerson("1");
        Assert.IsNotNull(p);
        Assert.AreEqual(p.ID, "1");
    }

    [Test]
    public void TestGetSinglePersonWithInvalidID()
    {
        //Throwing
        personRepoMock.GetPersonByID(Arg.Any<string>()).Returns(x => 
        {
            throw new ArgumentException();
        });

        PersonService pServ = new PersonService(personRepoMock);
        Assert.IsNull(pServ.GetPerson("-1"));
    }
}

Uncomment to debug. 取消注释调试。

//System.Diagnostics.Debugger.Launch();

Any suggestions on style/conventions are welcome (I realise test names arent great right now). 欢迎提供有关样式/惯例的任何建议(我知道测试名称目前还不错)。

I will update with any information requested. 我将更新要求的任何信息。

Received is used for assertions while you are trying to use it in the exercising of the method under test. 当您尝试在被测方法中使用它时, Received用于断言。 At the time you called Received the method under test has not been invoked as yet so the mock has not received anything. 在您调用Received ,被测方法尚未被调用,因此该模拟还没有收到任何信息。 Thus test fails. 因此测试失败。

Consider the following 考虑以下

[Test]
public void TestGetAllPeople() {
    //Arrange
    var expected = peopleList.Count;
    personRepoMock.GetPeople().Returns(peopleList);
    var subject = new PersonService(personRepoMock);

    //Act
    var actual = subject.GetAllPeople().Count;

    //Assert
    Assert.AreEqual(expected, actual);
    personRepoMock.Received().GetPeople();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM