我正在启动一个Web应用程序,客户端在纯ExtJS和Grails中间层实现.该应用程序具有基于角色的授权,用户可以拥有许多细粒度的角色,如SOME_FORM_READ,SOME_FORM_UPDATE,SOME_DATA_DELETE,SOME_DATA_READ等.根据用户的角色,某些GUI元素需要被禁用或隐藏,而其他需要处于只读模式.
我在网上做了一些搜索,但没有找到专门解决这个问题的设计模式,所以我想出了自己的设计.我相信很多网络应用程序都会有类似的要求,所以我想在这里发布我的设计并听取人们的意见.我的设计绝不是一个完美的设计,但我希望它可以通过每个人的输入得到改善.虽然我正在使用ExtJS,但一般设计也应该适用于类似的框架,如GWT,Flex,Swing等.
我们需要在客户端层中处理有关授权的四种类型的代码(或信息):
GUI元素操作代码,例如:
panel.hide()form.setReadOnly(true)
GUI元素权限要求,例如:
form.requires('READ','FORM_READ_ROLE')
adminPanel.requires( 'ADMIN_ROLE')
用户权限信息,基本上是用户拥有的角色列表;
授权逻辑:根据用户权限确定要隐藏/禁用的元素;
设计的核心是单例,名为GUIPermissionManager,简称GPM.这是一种集中式设计,因为大多数代码都在GPM中,因此GUI元素不会受到授权代码的污染.这就是GPM的工作原理:
GUI元素(需要某些访问权限)通过GPM注册其权限信息,如下所示:
GPM.register(this,'DEPARTMENT_DELETE_ROLE'); //删除部门的按钮
GPM维护GUI权限注册列表
在用户登录时,GPM会收到分配使用的角色列表
GPM遍历GUI权限注册列表并基于用户权限,确定要隐藏的GUI部分,然后相应地调用element.hide()
问题:
大约半年前,我的组织开始使用Pact来创建/验证用Java编写的REST服务/微服务之间的合同.我们很难决定提供商测试的适当范围或把握应该是什么,并且会喜欢其他协议用户的经验.
基本上,讨论围绕提供程序测试中的mock/stub的位置进行演变.在服务中,您必须至少模拟对其他服务的外部调用,但您也可以选择模拟更接近REST资源类.
我们将其归结为两种选择:
1.第一个选项是提供者测试应该是严格的合同测试,并且只运用提供者服务的REST资源类,模拟/删除从那里使用的服务类/协调器等.此合同测试将通过组件测试进行扩充,该组件测试将测试由提供程序测试存根/模拟的部件.
2.第二个选项是使用提供程序测试作为组件测试,该测试将为每个请求执行整个服务组件.只有对其他组件的传递外部调用才会被模拟/存根.
这些是每个选项的专业人士的想法
选项1的专业版:
选项2的专业版:
我真的很想知道您的提供商测试通常在这方面的看法.有最好的做法吗?
澄清"组件"的含义:组件是微服务或更大服务应用程序中的模块.我们采用了来自Martin Fowlers的组件的定义http://martinfowler.com/articles/microservice-testing/.
提供者服务/组件通常在Jersey资源类中具有REST端点.此端点是Pact提供程序测试的提供程序端点.一个例子:
@Path("/customer")
public class CustomerResource {
@Autowired private CustomerOrchestrator customerOrchestrator;
@GET
@Path("/{customerId}")
@Produces(MediaType.APPLICATION_JSON)
public Response get(@PathParam("customerId") String id) {
CustomerId customerId = CustomerIdValidator.validate(id);
return Response.ok(toJson(customerOrchestrator.getCustomer(customerId))).build();
}
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,@ Aututired(我们使用spring)CustomerOrchestrator可以在运行提供程序测试时进行模拟,也可以注入真正的"Impl"类.如果您选择注入真正的"CustomerOrchestratorImpl.class",它将具有额外的@Autowired bean依赖项,而这些依赖项又可能具有其他...等等.最后,依赖项将最终出现在将进行数据库调用的DAO对象中,或者一个REST客户端,它将对其他下游服务/组件执行HTTP调用.
如果我们在上面的例子中采用我的"选项1"解决方案,我们将模拟CustomerResource中的customerOrchestrator字段,如果我们采用"选项2",我们将为CustomerResource中的每个依赖项注入Impl类(真实类)依赖图并创建模拟的数据库条目和模拟下游服务.
作为旁注,我应该提到我们很少在提供程序测试中实际使用真实数据库.在我们采用"选项2"的情况下,我们模拟了DAO类层,而不是模拟实际的数据库数据,以减少测试中移动部件的数量.
我们创建了一个"测试框架",可以自动模拟任何未在spring上下文中显式声明的Autowired依赖项,因此stubing/mocking对我们来说是一个轻量级的过程.这是运行CustomerResource并启动存根的CustomerOrchestrator bean的提供程序测试的摘录:
@RunWith(PactRunner.class)
@Provider("customer-rest-api")
@PactCachedLoader(CustomerProviderContractTest.class)
public class CustomerProviderContractTest {
@ClassRule
public static PactJerseyWebbAppDescriptorRule webAppRule = buildWebAppDescriptorRule();
@Rule
public PactJerseyTestRule jersyTestRule = new PactJerseyTestRule(webAppRule.appDescriptor);
@TestTarget public final Target target = new …
Run Code Online (Sandbox Code Playgroud) 我正在开发Adobe Flex应用程序.
我需要在插入时检测gps设备.目前,使用的是基于启发式的错误检测(它试图找到特定的文件/目录).它使用StorageVolumeInfo来发现插入的设备.
因此,我想知道是否有办法通过Flex获取USB ID.
Thx提前
我对是否应该考虑某种类型的测试功能或合同有疑问。
假设我有一个像 /getToolType 这样的 API,它接受一个 {object" "myObject"} 作为输入,并以 {type: "[az]+"} 的形式返回 type
客户端和服务器之间一致认为返回的类型将匹配一组字符串,比如 [hammer|knife|screwdriver],所以消费者决定在枚举中解析它们,当返回的类型未知时使用回退值。
消费者是否应该为每种类型(锤子、刀子、螺丝刀)包含一个测试用例,以确保生产者仍然遵守它总是返回的协议,例如,当使用锤子对象调用 /getToolType 时,小写字符串“hammer” ? 或者你会认为这样的测试用例是功能性的吗?为什么?
我正在测试微服务,并使用PactNet来创建和验证契约。我发现测试太脆弱,因为验证者正在检查确切的值而不是验证类型。
例如,我正在针对 GitHub API 进行测试并且测试有效。如果添加新的Repo,则该public_repos
值加一,测试失败。
有人用它来检查类型而不是具体值吗?
这是验证码:
[Test]
public void VerifyPact()
{
// Arrange.
var pactVerifier = new PactVerifier(() => { }, () => { });
pactVerifier.ProviderState("There is call with the name 'karlgjertsen'");
// Act.
using (var client = new HttpClient { BaseAddress = new Uri("https://api.github.com/users/karlgjertsen") })
{
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident / 6.0)");
// Assert.
pactVerifier
.ServiceProvider("GitHub API", client)
.HonoursPactWith("Pact Test")
.PactUri(@"C:\Pact\pacts\pact_test-git_api.json")
.Verify();
}
}
Run Code Online (Sandbox Code Playgroud)
这是 …
下面的 Json 包含三件事,我不知道如何在基于 lambda 的 DSL 中为 Pact 建模(并且我无法通过阅读https://github.com/DiUS/pact-jvm上提供的示例来弄清楚)/tree/master/pact-jvm-consumer-java8)。
Json 对象由 3 个属性组成;“Inventory”包含一个数组(只有一个元素长)和两个简单的键值对。
1) 如何使用基于 lambda 的 DSL 声明命名数组?
Inventory 数组中的第一个(也是唯一一个)对象由两个命名对象“Car”和“Camera”组成。
2) 如何使用基于 lambda 的 DSL 声明命名对象?
在“Camera”对象中,有一个名为“Conditions”的数组,其中包含两个字符串值。
3) 如何使用基于 lambda 的 DSL 在命名数组中声明两个示例字符串值?
{
"Inventory":[
{
"Car":{
"gearbox":"automatic",
"ProductId":30212
},
"Camera":{
"EndPrice":1235,
"Conditions":[
"FaultyButtons",
"FaultyCasing"
],
"ModelId":"650"
}
}
],
"IsSuccess":true,
"Info":"Ok"
}
Run Code Online (Sandbox Code Playgroud)