有谁知道It.IsAny<T>
FakeItEasy 中Moq的等价物?
我想断言用一个Type实例调用一个方法
v.Do(new Foo());
Run Code Online (Sandbox Code Playgroud)
我试过了:
A.CallTo(() => v.Do(A<Foo>.Ignored)).MustHaveHappened();
Run Code Online (Sandbox Code Playgroud)
但这也接受v.Do()
;
我有以下测试
[Test]
public void Attack_TargetWith3Damage_CausesAttackerToDeal3DamageToTarget()
{
var realAttacker = CreateCreature(damage: 3);
var wrappedAttacker = A.Fake<ICreature>(x => x.Wrapping(realAttacker));
var target = A.Fake<ICreature>();
wrappedAttacker.Attack(target);
A.CallTo(() => wrappedAttacker.DealDamage(target, 3)).MustHaveHappened();
}
Run Code Online (Sandbox Code Playgroud)
问题是,该呼叫DealDamage
从Attack
方法没有被注册,因为该方法中,this
是realAttacker
不是wrappedAttacker
攻击者因此调用该方法不被拦截.
我该如何测试这个断言?可以用FakeItEasy完成吗?是否有一个不同的模拟框架允许我测试它?
我最近试图使用FakeItEasy但是我无法在没有解决许多怪癖的情况下从具体类创建假.
我尝试了以下方法:
public class MyObject {
public MyObject(){}
}
...
MyObject fakeObject = A.Fake<MyObject>();
Run Code Online (Sandbox Code Playgroud)
这导致了一个没有匹配争议异常的构造函数
接下来我尝试了:
public class MyObject {
public MyObject(string temp){}
}
...
MyObject fakeObject = A.Fake<MyObject>(x => x.WithArgumentsForConstructor(() => new MyObject("temp")));
Run Code Online (Sandbox Code Playgroud)
这导致了类似的错误.
最后我试过:
public class MyObject {
//public MyObject(){}
}
...
MyObject fakeObject = A.Fake<MyObject>();
Run Code Online (Sandbox Code Playgroud)
这让我最终创造了假货.我很困惑为什么大多数伪造一个具体类的例子都提到这个,这比我发现它更容易?为什么使用上面的试验#2记录的方法不起作用?
伪造一个没有记录的具体类是否有一些限制?
我正在测试的应用程序充满了基于自定义委托的事件,例如:
public delegate void NameChangedHandler(string name);
public event NameChanged OnNameChanged;
...
public void ChangeYourName(string newName)
{
if( NameChanged != null )
NameChanged(newName);
}
Run Code Online (Sandbox Code Playgroud)
我想模拟生成这些事件的类,并将这些事件提升到被测试的类中.
我知道,FakeItEasy可以使用Raise.With()
的筹款活动与传统的事件签名 MyHandler(object sender, EventArgs e)
或MyHandler(EventArgs e)
,但我不知道在我的情况做.
有任何想法吗?
你会如何伪造以下内容:
public interface IBlah
{
Func<T, bool> ApplyFilter<T>(Func<T, bool> predicate) where T:IMessage;
}
Run Code Online (Sandbox Code Playgroud)
我想要的是假的简单地返回它的论点而不做任何改变.但是,我想验证假冒被称为一次.用例如下:
public class Something
{
public Something(IBlah blah) { _blah = blah; }
public bool DoSomething(SomeValue m, Func<SomeValue, bool> predicate)
{
Func<SomeValue, bool> handler = _blah.ApplyFilter(predicate);
return handler(m);
}
}
Run Code Online (Sandbox Code Playgroud)
即假冒需要作为通过,但我也需要能够验证它已被使用.
最好的方法是什么?
[请不要担心这个人为的例子......有很多事情在幕后进行,但我已将其简化为上面的例子.]
如何使用FakeItEasy框架检查Func是否被调用?
例子:
Func<bool> myFunc = () => true;
// Unfortunately this fails:
A.CallTo(myFunc.Invoke()).MustHaveHappened();
Run Code Online (Sandbox Code Playgroud) 我的代码中有以下调用:
var dbResults = new List<CrossReferenceRelationshipEF>();
dbResults = dateTimeFilter == null
? new List<CrossReferenceRelationshipEF>(
CrossReferenceRelationshipRepository.GetAll()
.ToList().OrderBy(crr => crr.ToPartner))
: new List<CrossReferenceRelationshipEF>(
CrossReferenceRelationshipRepository.SearchFor(
crr => crr.HistoricEntries
.Any(he => he.ModifiedDatetime > dateTimeFilter))
.ToList().OrderBy(crr => crr.ToPartner));
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用FakeItEasy来验证当dateTimeFilter
有一个值时,SearchFor(…)
正在我的存储库中使用正确的函数调用它.
所以我的测试看起来像这样:
A.CallTo(() => crossReferenceRelationshipRepositoryMock.SearchFor(A<Expression<Func<CrossReferenceRelationshipEF,bool>>>.That
.Matches(exp => Expression.Lambda<Func<DateTime>>(((BinaryExpression)exp.Body).Right).Compile().Invoke() == filterByDate)))
.MustHaveHappened(Repeated.Exactly.Once);
Run Code Online (Sandbox Code Playgroud)
哪个不对.什么是测试我是否SearchFor(…)
使用正确表达式调用的方法?
crr => crr.HistoricEntries.Any(he => he.ModifiedDatetime > dateTimeFilter)
Run Code Online (Sandbox Code Playgroud)
传入的实际值SearchFor(…)
是DateTime.MinValue
因此我将断言更改为:
A.CallTo(() => crossReferenceRelationshipRepositoryMock.SearchFor(A<Expression<Func<CrossReferenceRelationshipEF, bool>>>.That
.Matches(exp => Expression.Lambda<Func<DateTime>>(((BinaryExpression)exp.Body).Right).Compile().Invoke() == DateTime.MinValue)))
.MustHaveHappened(Repeated.Exactly.Once);
Run Code Online (Sandbox Code Playgroud)
这是失败的,我得到的例外是
System.InvalidCastException:
Unable to cast object of …
Run Code Online (Sandbox Code Playgroud) 有以下单元测试:
public interface ITestMe
{
object[] Values { get; }
}
[Test]
public void Test ()
{
var sut = A.Fake<ITestMe> ();
A.CallTo (() => sut.Values[0]).Returns (4);
Assert.That (sut.Values[0], Is.EqualTo (4));
}
Run Code Online (Sandbox Code Playgroud)
导致以下异常:
System.InvalidCastException : Unable to cast object of type 'System.Linq.Expressions.SimpleBinaryExpression' to type 'System.Linq.Expressions.InvocationExpression'.
at FakeItEasy.Expressions.CallExpressionParser.Parse(LambdaExpression callExpression)
at FakeItEasy.Configuration.FakeConfigurationManager.AssertThatMemberCanBeIntercepted(LambdaExpression callSpecification)
at FakeItEasy.Configuration.FakeConfigurationManager.CallTo(Expression1 callSpecification) at FakeItEasy.A.CallTo(Expression1 callSpecification)
Run Code Online (Sandbox Code Playgroud)
或者也许我不知道如何为索引器指定一个假的?
使用 FakeItEasy,有没有办法伪造只写属性的 setter?
我必须使用的界面类似于:
Interface IMyInterface
{
String Foo { set; }
}
Run Code Online (Sandbox Code Playgroud)
我尝试了以下但语法不起作用。
IMyInterface _myObject = A.Fake<IMyInterface>();
A.CallTo(() => _myObject.Foo).Invokes((String foo) => {
//save off foo
});
Run Code Online (Sandbox Code Playgroud)
我也试过这个,但语法错误。
IMyInterface _myObject = A.Fake<IMyInterface>();
A.CallTo(() => _myObject.set_Foo).Invokes((String foo) => {
//save off foo
});
Run Code Online (Sandbox Code Playgroud) 我试图使用FakeItEasy来模拟在C#中定义的接口
public interface IMyInterface
{
int HeartbeatInterval { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在F#测试我做
let myFake = A.Fake<IMyInterface>()
A.CallTo(fun () -> ((!myFake).HeartbeatInterval)).Returns(10) |> ignore
Run Code Online (Sandbox Code Playgroud)
在测试运行器中运行此结果
System.ArgumentException
Expression of type 'Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,System.Int32]' cannot be used for return type 'System.Int32'
事实上,它似乎是为任何返回类型执行此操作,例如,如果HeartbeatInterval返回类型,foo
则抛出的异常将是类型foo
而不是System.Int32
.
我做错了还是F#和FakeItEasy之间有些不兼容?
我已经想到使用Object Expression可能是一种更容易的方法.