使用弹簧对安全休息控制器进行单元测试

2024-04-17

我有一个使用 Spring Boot 编写的非常小的 REST 应用程序。

我想编写一个用于身份验证的单元测试,但即使我将 @MockWithUser 添加到测试中,我也会收到 401 错误。

重要的文件是

安全配置

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
    auth
            .inMemoryAuthentication()
            .withUser("user").password("password").roles("USER");
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers("/**")
            .hasRole("USER")
            .anyRequest()
            .permitAll()
            .and()
            .anonymous().disable()
            .exceptionHandling()
            .authenticationEntryPoint(new org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint("headerValue"));
}

带有控制器的 MainApp

@Controller
@RequestMapping("/test")
@ComponentScan
@SpringBootApplication
public class MainApp {


@RequestMapping(method= RequestMethod.GET)
public @ResponseBody String sample(){

    return "Test";
}

public static void main(String[] args) throws Exception {
    SpringApplication.run(MainApp.class, args);
}
}

最后是测试(不起作用)

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = MainApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AuthenticationTest {

@Autowired
private TestRestTemplate testRestTemplate;

@Autowired
private WebApplicationContext context;

@Autowired
private Filter springSecurityFilterChain;

private MockMvc mvc;

@LocalServerPort
private int port;

@Before
public void setup() {
    mvc = MockMvcBuilders
            .webAppContextSetup(context)
            .addFilters(springSecurityFilterChain)
            .build();
}

@Test
@WithMockUser(username="admin",roles={"USER","ADMIN"})
public void shouldReturn200WhenSendingRequestToControllerWithRoleUser() throws Exception {
    then(SecurityContextHolder.getContext().getAuthentication().isAuthenticated());
    mvc.perform(get("/test")).andExpect(status().isOk());

}

@Test
@WithMockUser(username="admin",roles={"USER","ADMIN"})
public void shouldAuthenticatedBeTrueWithRoleUser() throws Exception {
    then(SecurityContextHolder.getContext().getAuthentication().isAuthenticated());
}
}

如您所见,有两个测试用例。第二个已通过,第一个未通过(接收 401,而不是 200 作为响应代码,堆栈跟踪如下)。

您能告诉我如何正确测试身份验证吗?

java.lang.AssertionError:预期状态: 但实际为: 在 org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54) 在 org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81) 在 org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664) 在 org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171) 在 graphEndpoint.dataConnection.controller.AuthenticationTest.shouldReturn200WhenSendingRequestToControllerWithRoleUser(AuthenticationTest.java:64) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 在 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 在 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 在 org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75) 在 org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86) 在 org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84) 在 org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252) 在 org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 在 org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 在 org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) 在org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114) 在 org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57) 在org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66) 在org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) 在 org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) 在org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32) 在 org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInitationHandler.invoke(ProxyDispatchAdapter.java:93) 在 com.sun.proxy.$Proxy3.processTestClass(来源未知) 在org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:109) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) 在 org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) 在 org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:377) 在 org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54) 在 org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745)


仅仅使用 addFilters 不足以构建安全上下文。这里有几个解决方案:

在您的设置方法中替换

.addFilters(springSecurityFilterChain)

with

.apply(springSecurity())

from

org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;

仅此一点就可以解决测试失败的问题。这仍然给您留下一个看起来令人讨厌的类,可以使用 WebMvcTest 对其进行大量清理。这是使用 WebMvcTest 的更简洁的测试版本。

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = MainApp.class)
public class AuthenticationTest {

    @Autowired
    private MockMvc mockMvc;

    @Test
    @WithMockUser(username = "admin", roles = {"USER", "ADMIN"})
    public void shouldReturn200WhenSendingRequestToControllerWithRoleUser() throws Exception {
        mockMvc.perform(get("/test")).andExpect(status().isOk());
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用弹簧对安全休息控制器进行单元测试 的相关文章

随机推荐

  • 安装 Sqlite3 for Ruby (Mac OSX 10.5.8)

    我正在遵循本 ATM 指南 http guides rubyonrails org getting started html getting up and running quickly with scaffolding http guid
  • 使用 OCaml 收集外部命令的输出

    在 OCaml 中调用外部命令并收集其输出的正确方法是什么 在Python中 我可以做这样的事情 os popen cmd read 如何在 OCaml 中获取外部程序的所有输出 或者 更好的是 带有 Lwt 的 OCaml Thanks
  • HasThis 和 ExplicitThis 调用约定

    我遇到HasThis and ExplicitThis调用约定 NET框架参考源 https referencesource microsoft com mscorlib system reflection callingconventio
  • 当一个对象被分配给另一个对象时会发生什么

    public class DrumKitTestDrive param args public static void main String args TODO Auto generated method stub Echo e1 new
  • Java 中枚举类型的强制初始化

    我试图找到一种方法来强制 Java 加载 初始化枚举类型 嵌套在包含静态 Map 的类中 这对我来说很重要 因为枚举类型有一个填充所述映射的构造函数 并且如果没有显式方法来初始化此枚举 则映射将保持为空 我尝试过使用Class forNam
  • Tensorflow:如何查看张量板中的检查点?

    假设我有内容检查点 checkpoint model ckpt 240000 data 00000 of 00001 model ckpt 240000 index model ckpt 240000 meta 是否可以在张量板中查看检查点
  • 将 webpack(环境)变量传递给 scss 文件

    对 webpack 非常陌生 我希望能够读取一个值 在本例中具体是env from webpack config js in a sass文件 这样我就可以根据环境有不同的CSS 例如 env 开发 颜色 绿色 env 生产 颜色 蓝色 到
  • 比较没有毫秒的日期时间

    I need to compare dates in two separate list Each list is constructed of MyFile Objects That is a class that I created i
  • Spring Data 和具有分页功能的本机查询

    在一个网络项目中 使用最新的 spring data 1 10 2 和 MySQL 5 6 数据库 我尝试使用带分页的本机查询 但我遇到了org springframework data jpa repository query Inval
  • 如何更改appBar后退按钮颜色

    我不知道如何将应用程序栏的自动后退按钮更改为不同的颜色 它在脚手架下 我试图研究它 但我无法理解它 return Scaffold appBar AppBar backgroundColor Colors white title Image
  • 您上传的二进制文件无效。使用 SDK 的预发布测试版来构建应用程序

    我在将新应用程序提交到应用程序商店时遇到问题 Itunes Connect 给我错误 您上传的二进制文件无效 SDK 的预发布测试版用于构建该应用程序 我没有更改任何内容 我可以编译为临时证书并且工作正常 我昨天上传了另一个应用程序 效果也
  • 如何用CSS取消选择?

    我想从选择中取消选择 id 项目 而不更改 HTML 或添加任何类名 假设我想在 CSS 中模拟这个 Jquery 句子 img not thisone CSS 是否可以 使用 CSS3 not 选择器 它具有等效的jQuery 选择器 h
  • 比较两个 Date 实例是否指同一天

    我有两个 java util Date 的 Java 实例 我必须查明它们是否指同一天 我可以用困难的方法来做到这一点 将日期分开并比较日期 确保年份也匹配 由于这是一个很常见的问题 我希望有一个更简单的解决方案来解决这个问题 Thanks
  • 处理innoDB死锁

    我一直在得到一个Deadlock found when trying to get lock try restarting transaction我的 InnoDB 表上出现错误 这是查询 UPDATE views SET visit cn
  • 如何解决PHP扩展“0”必须加载的问题?

    我正在尝试在我的服务器上安装 Magento 我做了一切 正如文档中所写的 我有以下错误 必须加载 PHP 扩展 0 当我尝试在浏览器中的第二页上配置 Magento 时 会发生这种情况 你知道如何解决这个问题吗 如果您安装的是 Magen
  • PHP 表单从 id 发送值而不是值

    我通常在带有隐藏字段的表单中做类似的事情
  • 如何查找总和位于给定值范围内的整数数组中的所有有序元素对

    给定一个整数数组 查找数组中总和位于给定范围 a b 内的所有有序元素对的数量 这是一个 O n 2 的解决方案 counts all pairs in array such that the sum of pair lies in the
  • 在 JavaScript 中使用 Rails 变量时转义引号?

    我在尝试在 javascript 代码中使用 Rails 变量时遇到问题 例如 我可能定义一个 link to remote 带有参数 complete gt alert my var If my var I m testing 那么 ja
  • 任务似乎自动开始

    我正在移植一个加载时间很长的程序 当我移植它时 它根本没有得到改善 因为缓慢是因为访问数据库服务器 而不是次优代码 我已将加载移动到一个单独的线程上Tasks库 现在 UI 在加载时不会冻结 但它确实让我对某些事情感到好奇 The Task
  • 使用弹簧对安全休息控制器进行单元测试

    我有一个使用 Spring Boot 编写的非常小的 REST 应用程序 我想编写一个用于身份验证的单元测试 但即使我将 MockWithUser 添加到测试中 我也会收到 401 错误 重要的文件是 安全配置 Configuration