如何模拟扩展 IEnumerable 的接口
我正在使用 Moq,并且有以下界面:
public interface IGameBoard : IEnumerable<PieceType>
{
...
}
public class GameBoardNodeFactory
{
public virtual GameBoardNode Create (int row, int column, IGameBoard gameBoard)
{
...
}
}
然后我有一个这样的测试:
var clonedGameBoardMock = new Mock<IGameBoard> (MockBehavior.Loose);
var gameBoardNodeFactoryMock = new Mock<GameBoardNodeFactory> ();
gameBoardNodeFactoryMock.Setup (x =>
x.Create (
position.Row,
position.Column,
clonedGameBoardMock.Object)).Returns (new GameBoardNode { Row = position.Row, Column = position.Column });
但随后 gameBoardNodeFactoryMock.Object.Create (position.Row,position.Column, clonedGameBoardMock.Object) 抛出 NullReferenceException。我尝试为 IGameBoard 创建一个模拟,以便它不会扩展 IEnumerable
任何帮助表示赞赏。
I'm using Moq and I have the following interface:
public interface IGameBoard : IEnumerable<PieceType>
{
...
}
public class GameBoardNodeFactory
{
public virtual GameBoardNode Create (int row, int column, IGameBoard gameBoard)
{
...
}
}
Then I have a test like this:
var clonedGameBoardMock = new Mock<IGameBoard> (MockBehavior.Loose);
var gameBoardNodeFactoryMock = new Mock<GameBoardNodeFactory> ();
gameBoardNodeFactoryMock.Setup (x =>
x.Create (
position.Row,
position.Column,
clonedGameBoardMock.Object)).Returns (new GameBoardNode { Row = position.Row, Column = position.Column });
But then gameBoardNodeFactoryMock.Object.Create (position.Row, position.Column, clonedGameBoardMock.Object) throws a NullReferenceException. I tried to create a mock for the IGameBoard such that it doesn't extend IEnumerable<PieceType> interface and then it works.
Any help is appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果调用 GetEnumerator(),则需要为它创建一个安装程序。类似于:
请注意确定这是否是本例中的问题,但如果您需要模拟
IEnumerable
,则值得注意。You would need to create a Setup for GetEnumerator() if it's being called. Something like:
Note sure if that's the issue in this case, but worth noting if you ever need to mock
IEnumerable<T>
.@DanBryant 的回答也是我们解决方案的关键。但是,在这种情况下,枚举器可能会被意外重用。相反,我建议使用:
这是一个完整的重现(使用 NUnit 2.6.4 和 Moq 4.2 的新类库):
对于它的价值/让这个问题向那个与我有同样问题的孤独 Google 员工弹出:上面是Couchbase .NET 客户端
IView
接口的抽象版本,它还实现IEnumerable
。The answer by @DanBryant was also the key to our solution. However, the enumerator in that case might be accidentally reused. Instead, I suggest using:
Here's a full repro (new class library using NUnit 2.6.4 and Moq 4.2):
For what it's worth / to make this question pop up to that one lone Googler with the same problem I had: the above is an abstracted version of the Couchbase .NET client's
IView<T>
interface, which also implementsIEnumerable<T>
.在这种情况下,空引用通常意味着您的设置从未得到满足。这意味着它永远不会以您设置的确切值来调用。为了调试这个,我将通过使用 It.IsAny() 等来减少匹配的限制,以确保测试将匹配对模拟函数的任何调用。在大多数情况下,这已经足够了。您尝试匹配特定值的原因是什么?
A null reference in this situation usually means your setup was never met. Meaning it was never called with the exact values you set it up for. To debug this I would make your match less constraining by using It.IsAny() and so on to make sure the test will match on any call to the mocked function. In most cases this is good enough. Any reason why your are trying to match on specific values?
好吧,如果有人感兴趣,我将 Moq 更新到版本 4,现在一切都按预期进行。
Okay if anyone is interested, I updated Moq to version 4 and now everything works as expected.