为什么这个 NSubstitute Received Call 会失败?
Why does this NSubstitute Received Call Fail?
有问题的测试:"TestGetAllPeople()"
我正在尝试使用单元测试框架(因为我没有太多使用它们的经验)并且我遇到了一个我看不到的错误。
根据文档 (https://nsubstitute.github.io/help/received-calls/)(我相信)。它不应该失败,因为我 运行 它通过调试器并被调用,它检索了两个人,所以我显然遗漏了一些东西。
- VS2015,
- .NET 4.5.2,
- N替换3.1,
- NUnit 3.9 和
- NUnitAdapter 3.9.
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
}
}
}
测试
[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"));
}
}
取消注释以进行调试。
//System.Diagnostics.Debugger.Launch();
欢迎就 style/conventions 提出任何建议(我知道现在测试名称不是很好)。
我会更新所要求的任何信息。
Received
用于断言,而您试图在执行被测方法时使用它。在您调用 Received
时,尚未调用被测方法,因此模拟尚未收到任何信息。因此测试失败。
考虑以下
[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();
}
有问题的测试:"TestGetAllPeople()"
我正在尝试使用单元测试框架(因为我没有太多使用它们的经验)并且我遇到了一个我看不到的错误。
根据文档 (https://nsubstitute.github.io/help/received-calls/)(我相信)。它不应该失败,因为我 运行 它通过调试器并被调用,它检索了两个人,所以我显然遗漏了一些东西。
- VS2015,
- .NET 4.5.2,
- N替换3.1,
- NUnit 3.9 和
- NUnitAdapter 3.9.
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
}
}
}
测试
[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"));
}
}
取消注释以进行调试。
//System.Diagnostics.Debugger.Launch();
欢迎就 style/conventions 提出任何建议(我知道现在测试名称不是很好)。
我会更新所要求的任何信息。
Received
用于断言,而您试图在执行被测方法时使用它。在您调用 Received
时,尚未调用被测方法,因此模拟尚未收到任何信息。因此测试失败。
考虑以下
[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();
}