我目前正在阅读Rober Martin(UncleBob)的"清洁代码",并且一般都喜欢UncleBob的沉思.但是,当我读到他避免使用像"IPerson"这样的接口前缀时,我有点困惑.他说:"我不希望我的用户知道我正在为他们提供一个界面".
从TDD /注入角度思考,我总是非常有兴趣告诉我正在处理接口的类的"用户".主要原因是我认为接口在系统的不同"代理"之间收缩.在我的系统的一个角落工作的代理,不应该知道另一个代理工作的具体实现; 他们只应该交换合同,并期望在不知道如何履行合同的情况下履行合同.另一个但也非常重要的原因是可以完全模拟界面,从而使单元测试更容易.你可以在具体课上嘲笑多少是有限的.
因此,我更愿意想象我确实在交接接口......或者以接口作为参数.但是因为UncleBob是我们社区中的重量级冠军,而我只是另一位flyweigth桌面骑师,我想知道我是否遗漏了一些东西.
我坚持使用接口是不对的?
tdd unit-testing dependency-injection coding-style interface
我尝试尽可能多地使用TDD.当我这样做的时候,我会把所有与外面的通信装在包装课上.几分钟前,我为静态类创建了一个包装器Directory,所以我可以在不与实际文件系统通信的情况下测试我的其他代码.
但是单元测试包装器本身呢?因为我使用TDD,所以我没有为它编写测试.另一方面,它是一个包装,没有别的,所以我真的需要吗?
我注意到你可以通过将抽象类实例化为一个模拟对象来对它进行单元测试.因此,您可以模拟抽象属性和方法,同时能够测试已实现的属性和方法.
但是,我习惯于区分要测试的类和注入到mock/stub的依赖项.那么,在我新启蒙的早期阶段,我想知道这种测试方法是否有任何陷阱?有什么想法吗?
此致,莫滕
我想通过XmlNodeList循环.你如何模拟Moq中的XmlNodeList,所以你可以像在foreach循环中一样遍历它:
foreach (XmlNode xmlNode in nodes)
{
//Do something with node
}
Run Code Online (Sandbox Code Playgroud)
我试图通过SetupSequence方法设置,但我无法创建所需的模拟.
我正在尝试Moq,而且我已经陷入了一个非常基本的例子.我想模拟一个非常简单的接口IInput:
namespace Example
{
public interface IInput
{
int SomeProperty { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
这似乎是一件非常容易的工作.但是,当我尝试在以下测试代码中模拟它时,我收到编译错误:
using Moq;
using NUnit.Framework;
namespace FirstEniro._Test
{
[TestFixture]
class TestFirstClass
{
[Test]
public void TestConstructionOk()
{
var mock = new Mock<IInput>();
mock.Setup(r => r.SomeProperty).Returns(3);
var x = new FirstClass(mock);
Assert.That(x, Is.EqualTo(3));
}
}
}
Run Code Online (Sandbox Code Playgroud)
编译器说"无法转换Moq.Mock<Example.IInput>为<Example.IInput>.我看不出我做错了什么.请帮助我
我在设置模拟时遇到问题,所以我可以调用Marshal.ReleaseComObject()我的Mocked对象.
我正在使用Moq来设置类型为IFeature的模拟(来自第三方接口库).模拟设置非常简单:
var featureMock = new Mock<IFeature>();
IFeature feature = featureMock.Object;
Run Code Online (Sandbox Code Playgroud)
在我的代码中,feature对象是在while循环中创建的,通过一种cursor(FeatureCursor)运行.由于第三方库的遗留问题,该Feature对象已知存在内存泄漏问题.因此,我必须释放对象Marshal.ReleaseComObject(),如代码中所示;
public class XXX
{
public void DoThis()
{
IFeatureCursor featureCursor;
//...fill the cursor with features;
IFeature feature = null;
while ((feature = featureCursor.NextFeature)!= null)
{
//Do my stuff with the feature
Marshal.ReleaseComObject(feature);
}
}
}
Run Code Online (Sandbox Code Playgroud)
它在我使用真实的特征光标和特征时有效,但是当我在单元测试中模拟该特征时,我得到一个错误:
"System.ArgumentException : The object's type must be __ComObject or derived from __ComObject."
Run Code Online (Sandbox Code Playgroud)
但是如何将其应用于我的Mock对象?
我已经使用了一段时间的模式.而且我想知道我做的是否正确.我有一个侦听事件的控制器类,并在引发事件时执行私有方法.它有点像这样:
public class MyController
{
public MyController(IMyEventRaiser eventRaisingObject)
{
eventRaisingObject.MyEvent += HandleEvent;
}
private void HandleEvent(object sender, EventArgs args)
{
// SOME STUFF I WANT TO TEST!!
}
}
public class EventRaisingClass : IMyEventRaiser
{
public event EventHandler<EventArgs> MyEvent;
}
Run Code Online (Sandbox Code Playgroud)
在MyController.HandleEvent中测试代码的唯一方法是创建一个存根:IMyEventRaiser,它会引发代码.
我不确定这种设计是否合适.一方面,我想将HandleEvent方法保持为私有,以便说明只有一个事件可以触发它.另一方面,私有方法包含关键业务逻辑,因此我觉得它应该是公共的或至少是内部的,这也使得单元测试更容易.
你觉得怎么样?
此致,莫滕
我在模拟对象上引发事件时遇到问题。我正在使用Rhino Mocks 3.4。我研究过类似的问题,但未能重现任何建议的解决方案。
我有一个类 - Foo - 它有一个私有方法,只能通过注入接口 - IBar 的事件调用来访问。
如何从 RhinoMock 对象引发事件 IBar.BarEvent,以便我可以在 Foo 中测试该方法?
这是我的代码:
[TestFixture]
public sealed class TestEventRaisingFromRhinoMocks
{
[Test]
public void Test()
{
MockRepository mockRepository = new MockRepository();
IBar bar = mockRepository.Stub<IBar>();
mockRepository.ReplayAll();
Foo foo = new Foo(bar);
//What to do, if I want invoke bar.BarEvent with value =123??
Assert.That(foo.BarValue, Is.EqualTo(123));
}
}
public class Foo
{
private readonly IBar _bar;
private int _barValue;
public Foo(IBar bar)
{
_bar = bar;
_bar.BarEvent += BarHandling; …Run Code Online (Sandbox Code Playgroud) 我刚刚回答了一个与SRP有关的问题让我想到:SRP如何站在实用工具类上?
根据定义,实用程序类往往会做很多事情.我可以看到单个接入点上的gatering相关实用程序是如何有用的.按照SRP标准,您无法在一个类中实现实用程序.这是否意味着实用程序类是禁止的,或者SRP是否允许它,如果它只是多个类的外观,每个类都遵循SRP?
Exception是一个方便的容器,很有可能用于各种目的.但是可以使用它来处理代码中的合法状态吗?
我的例子:我有一个几何函数,可以在搜索半径内找到最近的对象:
public IPoint FindNearest(IPoint origin, double searchRadius)
{
}
Run Code Online (Sandbox Code Playgroud)
我的想法是,当搜索没有找到命中时,我可以抛出异常.但这是个好主意吗?或者,我可以返回Null(我不喜欢),或返回结果对象而不是Point.
我有这种情况:
public class FOO<T> where T : IBar
{
private T _xxx;
public Y(T xxx)
{
if (xxx == null) throw new ArgumentNullException("xxx");
_xxx = xxx;
}
}
public interface IBar
{
string XString { get; }
}
Run Code Online (Sandbox Code Playgroud)
在构造函数中,我检查T了null.编译器正确警告我,我正在检查null可能是值类型的东西,可以IBar由结构实现.
如何约束T成为引用类型?
传递委托和将接口传递给方法之间是否存在重大差异?我将c#delegate视为"方法接口".从这个角度来看,传递委托和仅使用一个方法传递瘦接口之间没有区别.我尝试制作小型接口(SRP),所以我总是认为委托有些多余.但我错过了什么吗?
你好,我是C#的初学者.我已经为二次方程做了这个代码.它运行但没有给出正确的答案.
using System;
using System.Diagnostics;
namespace mynamespace
{
class myclass
{
static void Main(string[] args)
{
float a, b, c, x1, x2;
Console.Write("Enter Value in a");
a=Convert.ToSingle(Console.ReadLine());
Console.WriteLine("Enter Value in b");
b=Convert.ToSingle(Console.ReadLine());
Console.WriteLine("Enter Value in c");
c=Convert.ToSingle(Console.ReadLine());
x1=(-b + Math.Sqrt ( b*b - 4*a*c)/(2*a));
x2=(-b - Math.Sqrt ( b*b - 4*a*c)/(2*a));
Console.WriteLine(x1);
Console.WriteLine(x2);
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud) c# ×10
unit-testing ×8
tdd ×4
moq ×3
nunit ×3
.net ×2
mocking ×2
coding-style ×1
delegates ×1
events ×1
exception ×1
generics ×1
inheritance ×1
interface ×1
math ×1
quadratic ×1
rhino-mocks ×1