测试是否使用不同的参数调用了两次方法
Testing whether a method was called twice with different arguments
我需要验证某个方法是否已使用特定参数调用了 2 次:
public void Execute()
{
Counter с = new Counter(1);
// Basically, I need to verify that DoSomething method was called twice:
// First time with an argument, which internal value is 1...
_subject.DoSomething(с);
c.Increment();
// ... and the second time - with internal value of 2
_subject.DoSomething(c);
}
这是我的验证部分,两个断言都失败了:
// Fails with message "Expected invocation on the mock once, but was 0 times"
mock.Verify(
m => m.DoSomething(
It.Is<Counter>(
x => x.GetValue() == 1
)
),
Times.Once
);
// Fails with message "Expected invocation on the mock once, but was 2 times"
mock.Verify(
m => m.DoSomething(
It.Is<Counter>(
x => x.GetValue() == 2
)
),
Times.Once
);
所以问题是 Execute 方法中的两次调用都使用相同的参数,在执行断言时它包含 2 作为其内部值。
问题是如何让 mock 以某种方式“记录”参数,以便正确评估它们?
下面是完整列表:
[Test]
public void CheckSomething()
{
Mock<Subject> mock = new Mock<ISubject>();
mock.Setup(m => m.DoSomething(It.IsAny<Counter>()));
var myService = new MyService(mock.Object);
myService.Execute();
mock.Verify(m => m.DoSomething(It.Is<Counter>(x => x.GetValue() == 2)), Times.Once);
mock.Verify(m => m.DoSomething(It.Is<Counter>(x => x.GetValue() == 1)), Times.Once);
}
public interface ISubject
{
public void DoSomething(Counter с);
}
public class Subject : ISubject
{
public void DoSomething(Counter с)
{
// doesn't matter
}
}
public class MyService
{
private readonly ISubject _subject;
public MyService(ISubject subject)
{
_subject = subject;
}
public void Execute()
{
Counter с = new Counter(1);
_subject.DoSomething(с);
с.Increment();
_subject.DoSomething(с);
}
}
public class Counter
{
private int _val;
public Counter(int val)
{
_val = val;
}
public void Increment()
{
_val++;
}
public int GetValue()
{
return _val;
}
}
非常感谢任何反馈,谢谢!
您可以在设置 DoSomething
时设置回调以跟踪计数器值的增量。
int counterEqual1 = 0;
int counterEqual2 = 0;
mock.Setup(m => m.DoSomething(It.IsAny<Counter>()))
.Callback<Counter>(counter =>
{
if (counter.GetValue() == 1)
counterEqual1++;
else if (counter.GetValue() == 2)
counterEqual2++;
});
然后验证这些调用:
mock.Verify(m => m.DoSomething(It.IsAny<Counter>()), Times.Exactly(2));
Assert.That(counterEqual1, Is.EqualTo(1));
Assert.That(counterEqual2, Is.EqualTo(1));
我需要验证某个方法是否已使用特定参数调用了 2 次:
public void Execute()
{
Counter с = new Counter(1);
// Basically, I need to verify that DoSomething method was called twice:
// First time with an argument, which internal value is 1...
_subject.DoSomething(с);
c.Increment();
// ... and the second time - with internal value of 2
_subject.DoSomething(c);
}
这是我的验证部分,两个断言都失败了:
// Fails with message "Expected invocation on the mock once, but was 0 times"
mock.Verify(
m => m.DoSomething(
It.Is<Counter>(
x => x.GetValue() == 1
)
),
Times.Once
);
// Fails with message "Expected invocation on the mock once, but was 2 times"
mock.Verify(
m => m.DoSomething(
It.Is<Counter>(
x => x.GetValue() == 2
)
),
Times.Once
);
所以问题是 Execute 方法中的两次调用都使用相同的参数,在执行断言时它包含 2 作为其内部值。
问题是如何让 mock 以某种方式“记录”参数,以便正确评估它们?
下面是完整列表:
[Test]
public void CheckSomething()
{
Mock<Subject> mock = new Mock<ISubject>();
mock.Setup(m => m.DoSomething(It.IsAny<Counter>()));
var myService = new MyService(mock.Object);
myService.Execute();
mock.Verify(m => m.DoSomething(It.Is<Counter>(x => x.GetValue() == 2)), Times.Once);
mock.Verify(m => m.DoSomething(It.Is<Counter>(x => x.GetValue() == 1)), Times.Once);
}
public interface ISubject
{
public void DoSomething(Counter с);
}
public class Subject : ISubject
{
public void DoSomething(Counter с)
{
// doesn't matter
}
}
public class MyService
{
private readonly ISubject _subject;
public MyService(ISubject subject)
{
_subject = subject;
}
public void Execute()
{
Counter с = new Counter(1);
_subject.DoSomething(с);
с.Increment();
_subject.DoSomething(с);
}
}
public class Counter
{
private int _val;
public Counter(int val)
{
_val = val;
}
public void Increment()
{
_val++;
}
public int GetValue()
{
return _val;
}
}
非常感谢任何反馈,谢谢!
您可以在设置 DoSomething
时设置回调以跟踪计数器值的增量。
int counterEqual1 = 0;
int counterEqual2 = 0;
mock.Setup(m => m.DoSomething(It.IsAny<Counter>()))
.Callback<Counter>(counter =>
{
if (counter.GetValue() == 1)
counterEqual1++;
else if (counter.GetValue() == 2)
counterEqual2++;
});
然后验证这些调用:
mock.Verify(m => m.DoSomething(It.IsAny<Counter>()), Times.Exactly(2));
Assert.That(counterEqual1, Is.EqualTo(1));
Assert.That(counterEqual2, Is.EqualTo(1));