c# - RhinoMocks stub 具有简化的实现,尝试方法模式

标签 c# .net unit-testing mocking rhino-mocks

我想用 RhinoMocks 模拟一个相当大的存储库,主要是为了完全实现一个巨大且经常变化的接口(interface),而不是使用 VisualStudio 的“实现接口(interface)”默认实现(这需要为接口(interface)更新所有模拟更改并导致大量垃圾代码)。

我目前使用 stub ,但我还没有找到如何覆盖模拟的默认方法,除了定义每个可能的输入值。这在使用 bool TryGet(key, out value) 模式时以及当我需要默认行为时尤其糟糕,如果找不到 key (这里:返回 false/null,在其他情况下:抛出异常)。

在RhinoMocks中有什么方法可以实现方法转发吗?

public interface IMyRepository
{
    // would normally be implemented by database access
    bool TryGetNameById(int id, out string name);

    // more...
}

// within some other class:

public void SetupMockRepository()
{
    IDictionary<int, string> namesByIds = new Dictionary<int, string>() 
    //create and fill with mock values

    var mockRep = new MockRepository()
    var repStub = mockRep.Stub<IMyRepository>() 

    // something like this, forward inner calls,
    // without defining expected input values
    var repStub.Stub(r => r.TryGetNameById(int id, out string name)
        .OutRef((id) => (namesByIds.TryGetValue(id, out name) ? name : null))
        .Return((id) => namesByIds.ContainsKey(id)));
}

编辑:

我现在尝试了一个delegate,看起来好多了,但是还是有问题:

private delegate bool TryGet<TKey, TValue>(TKey key, out TValue value);

public void SetupMockRepository()
{
    // code from above omitted

    string outName;
    _stub.Stub(r=>r.TryGetNameById(0, out outName))
        .IgnoreArguments()
        .Do(new TryGet<int,string>(namesByIds.TryGetValue))
}

这是被接受的,但是当我运行它时,我得到一个 InvalidOperationException: “以前的方法 'TryGetValue(123)' 需要返回值或抛出异常”

最佳答案

您始终可以制作自己的假对象。通过混合模拟和部分模拟,您应该获得最大的灵 active 。

public interface IMyRepository
{
    bool TryGetNameById(int id, out string name);
}

public class FakeRepository : IMyRepository
{
    // public on purpose, this is for testing after all
    public readonly Dictionary<int, string> nameByIds = new Dictionary<int, string>();

    // important to make all methods/properties virtual that are part of the interface implementation
    public virtual bool TryGetNameById(int id, out string name)
    {
        return this.nameByIds.TryGetValue(id, out name);
    }
}

你的设置会变成这样:

public void Setup()
{
    var mock = MockRepository.GeneratePartialMock<FakeRepository>();
    mock.nameByIds.Add(1, "test");
}

如果您需要更复杂的行为,您仍然可以 stub 方法调用,因为所有方法都是虚拟的

关于c# - RhinoMocks stub 具有简化的实现,尝试方法模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30189700/

相关文章:

C# Enum.TryParse 解析无效数字字符串

c# - asp.net提交过程

c# - 在 C# 中以编程方式调整图像大小

c# - WPF 的有效拖放启用 ListView 实现?

java - Mockito 为了验证任何匹配器

C# HttpClient 在 Patch 请求中返回 415 Unsupported media type

java - 如何从从 C# 接收到的字节数组加载图像?安卓应用

c# - 在 Kinect 中使用 System.Speech

c# - 使用 InMemoryDatabase 和 Identity 列进行测试,如何处理?

java - Java/Junit 中的异步单元测试 - 一个非常简单但不成功的示例