如何指定Arg <t> .Matches()不应返回默认值(T)</t>

时间:2014-12-18 11:00:07

标签: c# .net rhino-mocks rhino-mocks-3.5

我对Rhino Mocks有点问题。

我有一个抽象类,其中一个方法需要一个对象(在一个字符串下面的示例中)。该方法检查参数是否为空。

public abstract class Foo
{
    public void DoSomething(string bar)
    {
        if (bar == null)
        {
            throw new ArgumentNullException("bar");
        }
    }
}

我有另一个类,它使用Foo

public class Baz
{
    private readonly Foo foo;

    public Baz(Foo foo)
    {
        this.foo = foo;
    }

    public void DoWork(string s)
    {
        s = "xxx" + s;
        this.foo.DoSomething(s);
    }
}

我想进行单元测试并检查是否使用正确的参数调用类DoSomething的{​​{1}}。我使用了Foo

Arg<T>.Matches()

现在,当我尝试运行此测试时,会在 [Test] public void TestMethod() { var fooMock = MockRepository.GenerateMock<Foo>(); var objectUnderTest = new Baz(fooMock); fooMock.Expect(x => x.DoSomething(Arg<string>.Matches(Text.StartsWith("xxx")))) .Repeat.Once(); objectUnderTest.DoWork("hello"); fooMock.VerifyAllExpectations(); } 处引发ArgumentNullException。我查看了Rhino Mocks的代码,发现Expect(...) - 方法始终返回Match(),对于字符串(以及其他所有类),它都是default(T)。因此,null签入会引发DoSomething()

我知道,我可以为ArgumentNullException提取接口并创建该接口的模拟,因此没有空检查。但我想知道这个问题是否可以通过保留代码来解决Rhino Mocks(当然除了单元测试;-))。

1 个答案:

答案 0 :(得分:-1)

仅通过更改测试代码无法解决问题。被测代码是以非测试友好的方式编写的。

原因是Rhino Mock需要模拟/存根方法才能被覆盖。即DoSomething()应为界面方法(如您所述)或虚拟方法
如果它是可覆盖的,则根本不会在DoSomething()调用中触发真实方法Expect()

这两个选项都可以工作,但都需要测试更改的代码。

如果可以修改测试中的代码,那么在我看来,IFoo而不是抽象类Foo的使用界面是可取的方式。这就是dependency injection应该正确实施的方式。