0

我对 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类。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();
    }

现在,当我尝试运行此测试时,出现了ArgumentNullExceptionat the Expect(...)。我查看了 Rhino Mocks 的代码,发现Match()-Method 总是返回default(T),这是null一个字符串(以及所有其他类)。所以签入DoSomething()引发了ArgumentNullException.

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

4

1 回答 1

-1

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

原因是 Rhino Mock 要求 mocked/stubbed 方法是可覆盖的。即DoSomething()应该是interface method(如您所描述的)或virtual method
如果它是可覆盖的,那么真正的方法DoSomething()根本不会在Expect()调用中被触发。

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

如果可以修改被测代码,那么在我看来,使用接口IFoo代替抽象类Foo是更可取的方式。因为这是正确实现依赖注入的方式。

于 2014-12-21T11:29:22.983 回答