小编bak*_*san的帖子

使用Moq"短路"无效方法?

我的团队最近决定使用Moq作为我们的模拟框架,因为它具有极大的灵活性和高度可读的语法.由于我们刚接触它,我在看似简单的问题上磕磕绊绊 - 搜索(这里,谷歌等)找到了关于Moq其他细微差别的大量讨论,但不一定是我所追求的,以及一些看似相关的问题变成了红色的鲱鱼.

我们正在测试一个具有外部依赖关系的类(确切地说是Amazon SimpleDb)但不希望我们的测试绑定到实时连接.一种特殊的方法:

  • 应用一些"业务"逻辑
  • 如果合适,通过我们建立的提供商调用SDB呼叫,让我们称之为 SaveItem()

我想对这进行单元测试,以便我们设置所需的上下文并确保SaveItem()调用它,但是以一种SaveItem()真正未被调用的方式(因为A)SDB的提供者是一个没有完全补充的模拟器,并且可能会炸弹和B)我不想为这笔交易付出数十万次).

在处理返回值的方法时,这很简单.

mockDb.Setup(d => d.GiveMeSomething()).Returns("Foo");
Run Code Online (Sandbox Code Playgroud)

在我概述的情况下,我的" SaveItem()"方法是无效的,因此使用Moq Returns()方法的选项不可用.虽然我可以设置一个回调来验证是否SaveItem()被调用,但我似乎无法让它实际上没有做任何事情.

天真/充满希望,我认为以下内容可行,但似乎仍然会调用该方法:

mockDb.Setup(d => d.SaveItem(It.IsAny<object>()));
Run Code Online (Sandbox Code Playgroud)

所以百万美元的问题:以下虚构代码的Moq是什么?

mockDb.Setup(d => d.SaveItem(It.IsAny<object>())).STOP_RIGHT_HERE();
Run Code Online (Sandbox Code Playgroud)

c# methods unit-testing moq mocking

30
推荐指数
1
解决办法
1万
查看次数

是HttpContextWrapper所有......有用吗?

我一直在完成清理控制器代码的过程,以使每个操作都可测试.一般来说,这并不是太困难 - 我们有机会使用固定对象,比如说FormsAuthentication,我们通常会在适当的时候引入某种形式的包装器并且是我们喜欢的方式.

由于没有特别与此对话密切相关的原因,在处理HttpContext的使用时,我们决定使用新创建的HttpContextWrapper类而不是发明自己开发的东西.我们介绍的一件事是能够交换HttpContextWrapper(比如说,用于单元测试).这完全受到Oren Eini使用DateTimes处理单元测试的方式的启发(参见文章,我们也使用的模式)

public static class FooHttpContext
{
    public static Func<HttpContextWrapper> Current = () 
         => new HttpContextWrapper(HttpContext.Current);

    public static void Reset()
    {
        Current = () => new HttpContextWrapper(HttpContext.Current);
    }
}
Run Code Online (Sandbox Code Playgroud)

没什么特别的花哨.它在我们的控制器代码中运行得很好.当我们去编写单元测试时,就会出现这个问题.我们使用Moq作为我们的模拟框架,但是唉

var context = new Mock<HttpContextWrapper>() 
Run Code Online (Sandbox Code Playgroud)

因为HttpContextWrapper没有无参数的ctor,所以会中断.作为ctor参数需要什么?一个HttpContext对象.所以我发现自己陷入困境22.

我正在使用规定的方法来解耦HttpContext - 但我无法模拟一个值,因为原始的HttpContext对象是密封的,因此很难测试.我可以映射HttpContextBase,它们都来自 - 但这并没有真正让我得到我想要的东西.我是否只是忽略了HttpContextWrapper的某个方面?

编辑以澄清意图

我们找到了解决问题的方法 - 但我想我们最终要解决的问题是HttpContextWrapper给表带来了什么价值?我不怀疑某个人完全有一个哈哈!它的时刻,但它不会来找我.我在这里看到的大多数帖子都在可测试性方面进行了讨论 - 但是我自己的经验让我相信它并没有带来太大的影响.除非我们做错了.(完全可能).

c# abstraction mocking

26
推荐指数
2
解决办法
1万
查看次数

/ sharedtypes等效于svcutil.exe?

构建一个依赖于第三方提供商的应用程序,该提供商拥有非常冗长的SOAP服务(我们正在讨论50多个WSDL文件).但是,每个单独的WSDL都有许多共享类型声明.使用wsdl.exe生成客户端代码时,曾经有一个/ sharedtypes标志,如果多次找到类型,它将合并重复的条目.

当我尝试生成我的客户端代码时,我会轰炸第三方在其所有WSDL文件中包含的这些重叠类型.

svcutil /t:code /importxmltypes [mypath]/*.wsdl
Run Code Online (Sandbox Code Playgroud)

导致错误消息导致类型冲突.例如,以下错误消息的几个示例:

Error: There was an error verifying some XML Schemas generated during export:
The simpleType 'http://common.soap.3rdparty.com:CurrencyNotation' has already been
declared.

Error: There was an error verifying some XML Schemas generated during export:
The complexType 'http://common.soap.3rdparty.com:NumberFormat' has already been 
declared.
Run Code Online (Sandbox Code Playgroud)

我无法控制WSDL的输出.我不想手动编辑WSDL,因为担心在运行时以某种方式破坏的错误很难追溯到我们编辑WSDL文件.更不用说有50个一些WSDL文件,其范围从200到1200行XML.(再次提醒我为什么我们认为SOAP在90年代后期对我们所有人来说都是伟大的救赎?)

c# soap wsdl svcutil.exe

17
推荐指数
1
解决办法
4311
查看次数

单元测试NHibernate w/SQLite和DateTimeOffset映射

移植应用程序以从不同的ORM使用NHibernate.

我已经开始实现对内存SQLite数据库运行单元测试的能力.这适用于前几批测试,但我只是遇到了障碍.我们的应用程序将在现实世界中与SQL 2008服务器通信,因此,几个模型当前具有DateTimeOffset属性.在非测试应用程序中映射到/来自SQL 2008时,这一切都正常.

在配置数据库或其他工具时是否有某种机制,以便当我使用来自我的SQLite测试夹具的会话时,DateTimeOffset的东西被"自动神奇地"处理为更平台无关的DateTime?

sqlite nhibernate datetimeoffset

14
推荐指数
2
解决办法
3190
查看次数

使用RabbitMQ的工作池和多租户队列

我致力于一个基于多租户云的应用程序的Web应用程序(许多客户端,每个客户端都有自己独立的"环境",但都在共享的硬件集上),我们正在引入用户批量处理的能力为以后的处理工作.批量工作的类型实际上并不重要,只有足够的数量才能在没有工作队列的情况下进行,这实际上并不实际.我们选择RabbitMQ作为底层队列框架.

因为我们是一个多租户应用程序,所以我们不一定希望客户端能够为另一个客户端造成冗长的队列处理时间,因此我们浮出水面的一个想法是在每个客户端基础上创建一个队列并拥有一个共享工作池指向所有客户端队列.问题在于,就我所能想到的最好,工人直接绑定到特定的队列,而不是交换.在我们理想的世界中,我们的客户端队列仍将被处理,而没有一个客户端阻止另一个客户端队列,我们​​可以通过启动更多工作人员或关闭空闲工作人员来根据需要增长或缩小共享工作者池.将工作人员绑定到特定队列会使我们在实际意义上无法做到这一点,因为我们经常会有很多工作人员闲置在没有活动的队列上.

是否有相对直接的目标来实现这一目标?我是RabbitMQ的新手,并没有真正完成我们所追求的目标.我们也不想编写一个非常复杂的多线程消费者应用程序,这是我们可能负担不起的开发时间和测试时间的时间.我们的堆栈是以Windows/.Net/C#为基础的,如果它是germaine,但我不认为这应该对手头的问题有重大影响.

worker amqp rabbitmq

13
推荐指数
2
解决办法
3917
查看次数

配置Fluent NHibernate映射只允许INSERT?

我正在将一个项目从SubSonic转移到NHibernate,我正在使用Fluent NHibernate来执行我们的所有映射.我们的数据库架构非常简单,我们的大部分案例到目前为止都可以通过不同的博客文章和可用的示例代码得到很好的说明.

然而,我无法弄清楚的一件事是能够映射列,以便只允许在数据的初始INSERT上设置其值.它是我们的应用层上的生成值,一旦插入,我们不希望允许它进一步更新.

我试过了明显的(但错了)

Map(x => Foo).ReadOnly()
Run Code Online (Sandbox Code Playgroud)

什么是适当的功能链来实现我追求的目标?

nhibernate fluent-nhibernate

9
推荐指数
1
解决办法
2197
查看次数

在类库中创建Ninject内核

我有一个类,它具有我与Ninject连接的依赖项.

public interface IFoo {}

public class MyObject {
    [Inject]
    IFoo myfoo;
}
Run Code Online (Sandbox Code Playgroud)

在真正的实现中,我正在使用属性注入,但为了快速说明,我将注入该字段.据我所知,我需要使用,而不是新建MyObject实例,以便正确地注入依赖项

kernel.Get<MyObject>()
Run Code Online (Sandbox Code Playgroud)

然而,我磕磕绊绊的是MyObject只会在类库的上下文中使用.目的是让最终应用程序创建自己的模块并将其传递给内核实例以进行水合.鉴于此,通常最实用的方法是将Ninject内核的通用实例呈现给我的类库,以便MyObject(和其他类似情况)的实例可以被水合?

我的第一个倾向是某种工厂内部化单例内核 - 应用程序本身必须通过加载模块来进行水合/初始化.

所以在RandomService.cs中

var myKernel = NinjaFactory.Unleash();
var myobj = myKernel.Get<MyObject>();
myobj.foo();
Run Code Online (Sandbox Code Playgroud)

在我走这条路之前,我需要做一个完整性检查,以确保思路健全,或者没有其他一些我不知道的东西.我显然是IoC的新手,感觉我喜欢基础知识,但不一定是最好的现实世界使用方式.

design-patterns ninject ioc-container

8
推荐指数
1
解决办法
5796
查看次数

非严格的多接口类型参数约束?

对不起,如果这是一个骗局,但我似乎无法得到正确的关键字组合来过滤各种类型约束和泛型问题(因为有很多).

我有两个接口 - 让我们称它们为IOnlineIOffline.

它们密切相关,因为它们描述了几乎相同的契约,但它们之间的关键差异之一是将使用具体实现的上下文.这不完全是我的情况,但它很好地说明了问题.

然后,我有一些方法可以对付这些接口的具体实现者.有时这些方法只想处理一种类型而不是另一种类型.

很简单:

public void DoStuff<T>(string foo) where T : IOnline {}
Run Code Online (Sandbox Code Playgroud)

踢球者正在实现可以在EITHER类型上操作的方法的代码.我认为这是正确的,但在阅读编译错误时,我期望约束将被解释为"允许任何类型T在这里一般使用,如果它们实现IOnline OR IOffline",实际上被解释为"允许任何类型"如果它们同时实现,则在这里使用T".

public void DoStuff<T>(string foo) where T : IOnline, IOffline {}
Run Code Online (Sandbox Code Playgroud)

尝试实现具有相同名称但不同约束的两个单独方法失败,因为存在明显的歧义问题 - 我们没有超载,因为参数列表是相同的(因为期望的行为是相同的).

可以为两个不同的方法使用两个不同的名称,每个方法都有适当的约束,但这看起来很糟糕,并使得下游的其他事情成为屁股的痛苦......可行但不理想.

我觉得必须有一些我在这里缺少的东西...我觉得在通用的土地上非常舒服,但这是我第一次完成我所追求的目标,我觉得我只是在旋转我的车轮atm.

c# generics type-constraints

6
推荐指数
1
解决办法
2368
查看次数

mvccontrib测试助手并验证http post路由和参数

在我的Asp.net MVC应用程序中,我在控制器上有两个方法,一个用于用户第一次到达视图时,另一个用于在所述视图上提交表单时.

public ActionResult Foo() {}

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Foo(string id, Account accountToFoo) {}
Run Code Online (Sandbox Code Playgroud)

在第二个动作中,有一个自定义模型绑定器正在组装我正在处理的帐户对象,尽管这并不重要.这一切都可以在服务器上进行本地测试.

我们尝试编写单元测试以测试所有不同的视图是否正确路由到包括HTTP POST的那些视图.为此,我们一直在使用mvccontrib的测试助手.

测试变得非常简单

"~/account/foo/myusername".
       Route().
       ShouldMapTo<AccountController>(c => c.Foo("myusername"));
Run Code Online (Sandbox Code Playgroud)

我的问题是在测试POST路由时,如何编写用于验证帖子是否正在接收准确值的lambda,类似于上面的GET测试?

对于POST,它看起来像:

"~/account/foo".
         WithMethod(HttpVerbs.Post).
         ShouldMapTo<AccountController>(a => something_something);
Run Code Online (Sandbox Code Playgroud)

这是我的lambda中的某些东西,我遇到了麻烦.使用任意值不起作用("a => a.Foo(0,new Account()").如何将预期值指定为测试的一部分?

编辑 我希望有一些类似于Moq对foo.Setup(s => s.Foo(It.IsAny(),It.Is(i => i> 32))等语句的lambdas的方式等等即使我必须明确提供值,这是可行的 - 我似乎无法理解所需的结构来传递这些显式值.

asp.net asp.net-mvc url-routing mvccontrib

6
推荐指数
1
解决办法
1959
查看次数

JSON 序列化,类继承自 Dictionary&lt;T,V&gt;

我有一个当前从 Dictionary 继承的类,然后向其中添加了一些第一类成员属性。大致:

public class Foo : Dictionary<string, string>
{
   public string Bar { get; set; }
   public string Baz { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然而,将此对象的实例序列化为 JSON 后,序列化程序似乎只发出我存储在字典中的键/值对。即使我将 DataMember 属性应用于新的第一类属性,JSON 序列化程序似乎也不知道如何处理这些属性,而是忽略它们。

我假设我缺少一些基本的基本知识,但是在 .net 的 JSON 序列化器上搜索代码示例和文档时,我只发现了一些与我正在做的事情不太匹配的琐碎示例。我们从其他基类派生的所有其他类似乎都没有表现出这个问题,特别是从通用字典派生的这个类让我们感到不舒服。

[编辑] 除了将字典作为一流属性移入 Foo 之外,还有什么办法可以实现这一点吗?我假设挂断是序列化器不知道如何“命名”字典以将其与其他成员区分开来?

c# serialization json dictionary

5
推荐指数
1
解决办法
3744
查看次数

RabbitMQ热衷于主题交流

对RabbitMQ来说很新,我们仍处于调查阶段,看它是否适合我们的用例 -

我们很容易得出结论,我们所需的拓扑结构将让我们部署一些基于主题的交换,然后从那里过滤到特定的队列.例如,假设我们有一个用户和一个上传交换,其中用户队列可能会收到主题为"新注册"或"朋友请求"的消息,并且上传交换可能会收到"视频上传"等消息或"图片上传".

创建队列,将它们路由到适当的队列,然后构建侦听器来处理各种队列的消息已经非常简单.

然而,我不清楚的是,是否可以在主题交换上进行扇动?

即我已经命名了与我的主题交换绑定的队列,但我希望能够在这些队列中抛出大量的听众实例以防止单点故障.但据我所知,RabbitMQ以直接的循环方式对待这些听众 - 例如,每个Nth消息总是转到相同的第N个侦听器,而不是向第一个可用的消费者发送消息.这通常是我们可以接受的,但考虑到我们预期的负担,我们希望避免在我们的消费者农场中出现热点的可能性.

那么,是否有某种方式,无论是在队列或交换配置中还是在消费者代码中,我们可以将我们的侦听器指向主题队列但是以扇出方式处理侦听器?

rabbitmq

4
推荐指数
2
解决办法
5715
查看次数