作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直在查看 the NuGetGallery 中的单元测试方式。 .我观察到当 Controller 被测试时,服务类被模拟了。这对我来说很有意义,因为在测试 Controller 逻辑时,我不想担心下面的架构层。在使用这种方法一段时间后,我注意到当我的服务类发生变化时,我经常在我的 Controller 测试中修复我的模拟。为了解决这个问题,在没有咨询比我聪明的人的情况下,我开始编写这样的测试(别担心,我还没有做到这一点):
public class PersonController : Controller
{
private readonly LESRepository _repository;
public PersonController(LESRepository repository)
{
_repository = repository;
}
public ActionResult Index(int id)
{
var model = _repository.GetAll<Person>()
.FirstOrDefault(x => x.Id == id);
var viewModel = new VMPerson(model);
return View(viewModel);
}
}
public class PersonControllerTests
{
public void can_get_person()
{
var person = _helper.CreatePerson(username: "John");
var controller = new PersonController(_repository);
controller.FakeOutContext();
var result = (ViewResult)controller.Index(person.Id);
var model = (VMPerson)result.Model;
Assert.IsTrue(model.Person.Username == "John");
}
}
public class PersonController : Controller
{
private readonly LESRepository _repository;
private readonly PersonService _personService;
public PersonController(LESRepository repository)
{
_repository = repository;
_personService = new PersonService(_repository);
}
public ActionResult Index(int id)
{
var model = _personService.GetActivePerson(id);
if(model == null)
return PersonNotFoundResult();
var viewModel = new VMPerson(model);
return View(viewModel);
}
}
最佳答案
唔。伙计,这里有几件事。
首先,看起来您正在尝试测试 Controller 方法。伟大的 :)
所以这意味着, Controller 需要的任何东西都应该被模拟。这是因为
public interface ILESRepository
{
IQueryable<Person> GetAll();
}
IRepository
真的很简单而且很棒。或者一个真实的例子。
public class PersonController : Controller
{
private readonly ILESRepository _repository;
public PersonController(ILESRepository repository)
{
if (repository == null)
{
throw new ArgumentNullException("repository");
}
_repository = repository;
}
public ActionResult Index(int id)
{
var model = _repository.GetAll<Person>()
.FirstOrDefault(x => x.Id == id);
var viewModel = new VMPerson(model);
return View(viewModel);
}
}
POCO
的一个无聊、简单的列表。的。
public static class FakePeople()
{
public static IList<Person> GetSomeFakePeople()
{
return new List<Person>
{
new Person { Id = 1, Name = "John" },
new Person { Id = 2, Name = "Fred" },
new Person { Id = 3, Name = "Sally" },
}
}
}
xUnit
对于我的测试框架和
moq
为了我的 mock 。任何框架都可以,在这里。
public class PersonControllerTests
{
[Fact]
public void GivenAListOfPeople_Index_Returns1Person()
{
// Arrange.
var mockRepository = new Mock<ILESRepository>();
mockRepository.Setup(x => x.GetAll<Person>())
.Returns(
FakePeople.GetSomeFakePeople()
.AsQueryable);
var controller = new PersonController(mockRepository);
controller.FakeOutContext();
// Act.
var result = controller.Index(person.Id) as ViewResult;
// Assert.
Assert.NotNull(result);
var model = result.Model as VMPerson;
Assert.NotNull(model);
Assert.Equal(1, model.Person.Id);
Assert.Equal("John", model.Person.Username);
// Make sure we actually called the GetAll<Person>() method on our mock.
mockRepository.Verify(x => x.GetAll<Person>(), Times.Once());
}
}
ILESRepository
的模拟。 .
GetAll<Person>()
方法,好吧 .. 不要 - 真的 - 访问数据库或文件或其他任何东西 .. 只需返回在
FakePeople.GetSomeFakePeople()
中创建的人员列表.
var model = _repository.GetAll<Person>()
.FirstOrDefault(x => x.Id == id);
GetAll<Person>()
方法。我只是“设置”以返回人员列表......所以我们有一个列表 3
Person
对象。接下来,我们再调用
FirstOrDefault(...)
在此列表中 3
Person
objects .. 返回单个对象或 null,具体取决于
id
的值。是。
Act
然后我们
Assert
.那里没什么难的。
verify
我们实际上调用了
GetAll<Person>()
方法,在 Controller 的
Index
内的模拟 ..方法。这是一个安全调用,以确保我们的 Controller 逻辑(我们正在测试)正确完成。
verify
他们从未被召唤。
关于asp.net-mvc-3 - 通过以下方式对 ASP.NET MVC 代码进行单元测试可能会出现哪些问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10359080/
java.lang.Throwable 的哪些子类可能被空语句抛出? 通过短语“空语句”,我指的是“无”、“分号”和“分号”: // .... A(); B(); C(); try { //
我是一名优秀的程序员,十分优秀!