GVKun编程网logo

如何使用@PathVariable对Spring MVC控制器进行单元测试?(spring mvc 单元测试)

16

本文将为您提供关于如何使用@PathVariable对SpringMVC控制器进行单元测试?的详细介绍,我们还将为您解释springmvc单元测试的相关知识,同时,我们还将为您提供关于asp.net-

本文将为您提供关于如何使用@PathVariable对Spring MVC控制器进行单元测试?的详细介绍,我们还将为您解释spring mvc 单元测试的相关知识,同时,我们还将为您提供关于asp.net-mvc – ASP.NET MVC – 使用Moq框架对RenderPartialViewToString()进行单元测试?、asp.net-mvc – 如何在没有IoC容器的情况下对您的控制器进行单元测试?、asp.net-mvc-3 – 如何使用MVC3中的存储库类进行单元测试?、java – Spring MVC 3.0:String是@PathVariable的首选类型吗?的实用信息。

本文目录一览:

如何使用@PathVariable对Spring MVC控制器进行单元测试?(spring mvc 单元测试)

如何使用@PathVariable对Spring MVC控制器进行单元测试?(spring mvc 单元测试)

如何解决如何使用@PathVariable对Spring MVC控制器进行单元测试??

从Spring 3.2开始,有一种合适的方法可以轻松,优雅地进行测试。你将可以执行以下操作:

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration("servlet-context.xml")
public class SampleTests {

  @Autowired
  private WebApplicationContext wac;

  private mockmvc mockmvc;

  @Before
  public void setup() {
    this.mockmvc = webAppContextSetup(this.wac).build();
  }

  @Test
  public void getFoo() throws Exception {
    this.mockmvc.perform(get("/foo").accept("application/json"))
        .andExpect(status().isOk())
        .andExpect(content().mimeType("application/json"))
        .andExpect(jsonPath("$.name").value("Lee"));
  }
}

解决方法

我有一个与此类似的简单带注释的控制器:

@Controller
public class MyController {
  @RequestMapping("/{id}.html")
  public String doSomething(@PathVariable String id,Model model) {
    // do something
    return "view";
  }
}

我想用这样的单元测试来测试它:

public class MyControllerTest {
  @Test
  public void test() {
    MockHttpServletRequest request = new MockHttpServletRequest();
    request.setRequestURI("/test.html");
    new AnnotationMethodHandlerAdapter()
      .handle(request,new MockHttpServletResponse(),new MyController());
    // assert something
  }
}

问题是AnnotationMethodHandlerAdapter.handler()方法引发异常:

java.lang.IllegalStateException: Could not find @PathVariable [id] in @RequestMapping
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.resolvePathVariable(AnnotationMethodHandlerAdapter.java:642)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolvePathVariable(HandlerMethodInvoker.java:514)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:262)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:146)

asp.net-mvc – ASP.NET MVC – 使用Moq框架对RenderPartialViewToString()进行单元测试?

asp.net-mvc – ASP.NET MVC – 使用Moq框架对RenderPartialViewToString()进行单元测试?

我正在使用这个帮助方法将我的PartialViewResult转换为字符串并将其作为Json – http://www.atlanticbt.com/blog/asp-net-mvc-using-ajax-json-and-partialviews/返回

我的问题是我使用Moq来模拟控制器,每当我运行使用这个RenderPartialViewToString()方法的单元测试时,我得到了“对象引用未设置为对象的实例”. ControllerContext上的错误.

private ProgramsController GetController()
{
var mockHttpContext = new Mock<ControllerContext>();
mockHttpContext.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("test");
mockHttpContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);
// Mock Repositories
var mockOrganizationRepository = new MockOrganizationRepository(MockData.MockOrganizationsData());
var mockIRenderPartial = new BaseController();
var controller = new ProgramsController(mockOrganizationRepository,mockIRenderPartial);
controller.ControllerContext = mockHttpContext.Object;
return controller;
}

这会返回一个代理控制器,也许这就是我收到错误的原因.知道如何对此进行单元测试吗?

非常感谢你.

解决方法

尝试这个:
public static void SetContext(this Controller controller)
        {
            var httpContextBase = new Mock<HttpContextBase>();
            var httpRequestBase = new Mock<HttpRequestBase>();
            var respone = new Mock<HttpResponseBase>();
            var session = new Mock<HttpSessionStateBase>();
            var routes = new RouteCollection();
            RouteConfigurator.RegisterRoutesTo(routes);

            httpContextBase.Setup(x => x.Response).Returns(respone.Object);
            httpContextBase.Setup(x => x.Request).Returns(httpRequestBase.Object);
            httpContextBase.Setup(x => x.Session).Returns(session.Object);
            session.Setup(x => x["somesessionkey"]).Returns("value");
            httpRequestBase.Setup(x => x.Form).Returns(new NameValueCollection());
            controller.ControllerContext = new ControllerContext(httpContextBase.Object,new RouteData(),controller);
            controller.Url = new UrlHelper(new RequestContext(controller.HttpContext,new RouteData()),routes);
        }

asp.net-mvc – 如何在没有IoC容器的情况下对您的控制器进行单元测试?

asp.net-mvc – 如何在没有IoC容器的情况下对您的控制器进行单元测试?

在构建我最新的ASP.NET MVC项目时,我开始进入单元测试,依赖注入和所有爵士乐.

我现在想要单元测试我的控制器,我很难搞清楚如何在没有IoC容器的情况下正确地执行此操作.

以一个简单的控制器为例:

public class QuestionsController : ControllerBase
{
    private IQuestionsRepository _repository = new sqlQuestionsRepository();

    // ... Continue with varIoUs controller actions
}

由于它直接实例化sqlQuestionsRepository,因此该类不是单元可测试的.那么,让我们沿着Dependancy Injection路线行进并做:

public class QuestionsController : ControllerBase
{
    private IQuestionsRepository _repository;

    public QuestionsController(IQuestionsRepository repository)
    {
        _repository = repository;
    }
}

这似乎更好.我现在可以使用模拟IQuestionsRepository轻松编写单元测试.但是,现在要实例化控制器的是什么?在调用链sqlQuestionRepository的某个地方必须进行实例化.似乎我只是简单地将问题转移到别处,而不是摆脱它.

现在,我知道这是一个很好的例子,IoC容器可以通过为我配置控制器依赖性来帮助您,同时保持我的控制器易于单元测试.

我的问题是,如何在没有IoC容器的情况下对这种性质的东西进行单元测试?

注意:我不反对IoC容器,我很快就会走这条路.但是,我很好奇对于那些不使用它们的人来说,替代方案是什么.

解决方法

是不是可以保持字段的直接实例化并提供setter?在这种情况下,您只需在单元测试期间调用setter.像这样的东西:

public class QuestionsController : ControllerBase
{
    private IQuestionsRepository _repository = new sqlQuestionsRepository();

    // Really only called during unit testing...
    public QuestionsController(IQuestionsRepository repository)
    {
        _repository = repository;
    }
}

我不太熟悉.NET,但作为Java的旁注,这是重构现有代码以提高可测试性的常用方法. I.E.,如果您有已经在使用的类并且需要修改它们以便在不破坏现有功能的情况下提高代码覆盖率.

我们的团队之前已经这样做了,通常我们将setter的可见性设置为package-private并保持测试类的包相同,以便它可以调用setter.

asp.net-mvc-3 – 如何使用MVC3中的存储库类进行单元测试?

asp.net-mvc-3 – 如何使用MVC3中的存储库类进行单元测试?

我正在尝试对我的控制器进行测试,这些控制器从存储库类中获取数据.
这是我要测试的存储库的一部分:

public class NewsRepository
{
    public IEnumerable<NewsItem> GetNews()
    {
        var result = (from n in n_db.NewsItems
                     orderby n.ID descending
                     select n).Take(3);
        return result;
    }
}

只是一些小代码来了解测试的工作原理.
在我的HomeController中,我在Index()中有这个代码:

public ActionResult Index()
    {
        ViewBag.Message = "Announcements";
        NewsRepository n_rep = new NewsRepository();
        var model = i_rep.GetNews();

        return View(model);
    }

我对测试完全陌生,所以所有解释都很棒.
谢谢.

解决方法

您的控制器无法单独进行单元测试,因为它与以下行中的存储库紧密耦合:

NewsRepository n_rep = new NewsRepository();

您只需硬编码存储库的特定实现,并且在单元测试中您无法模拟它.为了正确地执行此操作,您应该首先在此存储库上定义抽象:

public interface INewsRepository
{
    IEnumerable<NewsItem> GetNews();
}

然后让您的特定存储库实现此接口:

public class NewsRepository : INewsRepository
{
    ...
}

好了,现在我们有了一个抽象,让我们通过使用这个抽象来削弱数据访问和控制器逻辑之间的耦合:

public class NewsController: Controller
{
    private readonly INewsRepository repository;
    public NewsController(INewsRepository repository)
    {
        this.repository = repository;
    }

    public ActionResult Index()
    {
        ViewBag.Message = "Announcements";
        var model = this.repository.GetNews();
        return View(model);
    }    
}

好吧,现在你有一个控制器不再与某些特定的实现紧密结合.您可以拾取您最喜欢的模拟框架并编写单元测试.例如,对于NSubstitute,这里的Index操作的单元测试可能如下所示:

[TestMethod]
public void Index_Action_Fetches_Model_From_Repo()
{
    // arrange
    var repo = Substitute.For<INewsRepository>();
    IEnumerable<NewsItem> expectednews = new[] { new NewsItem() };
    repo.GetNews().Returns(expectednews);
    var sut = new NewsController(repo);

    // act
    var actual = sut.Index();

    // assert
    Assert.isinstanceOfType(actual,typeof(ViewResult));
    var viewResult = actual as ViewResult;
    Assert.AreEqual(expectednews,viewResult.Model);
}

这就是它.您的控制器现在可以单独进行单元测试.您不需要设置数据库或其他任何东西.这不是测试控制器逻辑的重点.

java – Spring MVC 3.0:String是@PathVariable的首选类型吗?

java – Spring MVC 3.0:String是@PathVariable的首选类型吗?

请原谅我在这里提出这样一个简单的问题,因为我是 Spring MVC 3.0的新手.我一直在阅读spring source website的文档几次.这是我在下面的问题中引用的代码片段: –
@RequestMapping("/pets/{petId}")
public void findPet(@PathVariable String petId,Model model) {    
// implementation omitted
}

如果我打算使用基于这个例子的URI模板,那么将@PathVariable类型设置为String总是比较好,即使我期望它是其他类型,例如int?文档说@PathVariable注释可以是任何简单类型,但如果Spring无法将无效petId转换为int(例如,用户输入一些字符而不是数字),它将抛出一个TypeMismatchException.

那么,验证器什么时候开始发挥作用?我是否将所有@PathVariable类型保留为String并使用验证器对String值执行验证,如果没有验证错误,则将String显式转换为所需类型?

谢谢.

解决方法

>让@PathVariable成为您期望的类型,不一定是String >有一个很好的自定义错误页面.如果用户决定在URL中写入内容,他应该知道“后果”.

我们今天的关于如何使用@PathVariable对Spring MVC控制器进行单元测试?spring mvc 单元测试的分享就到这里,谢谢您的阅读,如果想了解更多关于asp.net-mvc – ASP.NET MVC – 使用Moq框架对RenderPartialViewToString()进行单元测试?、asp.net-mvc – 如何在没有IoC容器的情况下对您的控制器进行单元测试?、asp.net-mvc-3 – 如何使用MVC3中的存储库类进行单元测试?、java – Spring MVC 3.0:String是@PathVariable的首选类型吗?的相关信息,可以在本站进行搜索。

本文标签: