2

如何将单元测试写入以下代码:

public Image Get(BrowserName browser)
{
    // if no screenshot mode specified it means that regular screenshot needed
    return this.Get(browser, ScreenshotMode.Regular);
}

public Image Get(BrowserName browser, ScreenshotMode mode) {            
    // some code omitted here
}
4

2 回答 2

3

这通常是通过部分模拟来完成的,它们可能有点恶心。

首先,您要模拟的方法必须是虚拟的。否则 Rhino Mocks 无法拦截该方法。因此,让我们将您的代码更改为:

public Image Get(BrowserName browser)
{
    // if no screenshot mode specified it means that regular screenshot needed
    return this.Get(browser, ScreenshotMode.Regular);
}

public virtual Image Get(BrowserName browser, ScreenshotMode mode) {            
    // some code omitted here
}

请注意,第二种方法现在是虚拟的。然后我们可以像这样设置我们的部分模拟:

//Arrange
var yourClass = MockRepository.GeneratePartialMock<YourClass>();
var bn = new BrowserName();
yourClass.Expect(m => m.Get(bn, ScreenshotMode.Regular));

//Act
yourClass.Get(bn);

//Assert
yourClass.VerifyAllExpectations();

这就是 AAA Rhino Mocks 语法。如果您更喜欢使用录制/播放,您也可以使用它。


所以你会这样做。一个可能更好的解决方案是 ifScreenshotMode是一个枚举并且您可以使用 C# 4,只需将其设为可选参数:

public Image Get(BrowserName browser, ScreenshotMode mode = ScreenshotMode.Regular)
{
    //Omitted code.
}

现在你没有两个方法,所以没有必要测试一个调用另一个。

于 2012-08-09T16:01:37.270 回答
1

除了使方法虚拟之外还有两种可能性(正如 vcsjones 解释的那样):

1)

为 Get(browser, mode) 编写一个测试,模式为常规。然后对 Get(浏览器)运行相同的测试。

毕竟两者都应该返回完全相同的结果。

或 2)

将第二个 Get 方法的代码提取到具有接口的类中,并使其可注入到测试的类中。调用它:

public Image Get(BrowserName browser) {
  return whatever.Get(browser, ScreenshotMode.Regular);
}

public Image Get(BrowserName browser, ScreenshotMode mode) {   
  return whatever.Get(browser, mode);
}

现在,在测试期间,您可以注入一个模拟并验证第一个 Get 方法是否使用 ScreenshotMode.Regular 调用它,而第二个 Get 方法只是传递模式。

于 2012-08-09T16:24:19.810 回答