在没有模拟框架的情况下编写单元测试
Writing unit test without mocking framework
我正在用 NUnit 和 NSubstiture 做一些单元测试。
我有这个class:
public class Presenter
{
public Presenter()
{
}
private readonly IView _view;
public Presenter(IView view)
{
_view = view;
this._view.Loaded += OnLoaded;
}
private void OnLoaded()
{
_view.Render("Hello Word");
}
}
我有这个界面:
public interface IView
{
event Action Loaded;
void Render(string text);
}
而且我已经使用 NSubstiture 框架进行了单元测试,如下所示:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithMockingFramework()
{
var mockView = Substitute.For<IView>();
Presenter p = new Presenter(mockView);
mockView.Loaded += Raise.Event<Action>();
mockView.Received().Render(Arg.Is<string>(s => s.Contains("Hello World")));
}
但现在我只想出于测试目的,编写相同的单元测试,但没有 NSubstiture 框架:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
IView view;
Presenter MockingVIew = new Presenter(view);
}
但是如何做到这一点?
谢谢
我这样试:
public class FakePresenter : IView
{
public event Action Loaded;
public void Render(string text)
{
}
}
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
//FakeMockingVIew = new Presenter(view);
FakePresenter fPresenter = new FakePresenter();
Presenter p = new Presenter(fPresenter);
fPresenter.Loaded += Raise.Event<Action>();
fPresenter.Received();
Assert.That(fPresenter, Is.EqualTo());
}
如果您不想再使用模拟框架,没有什么可以阻止您自己创建一个 IView
派生的 class 并将其用作测试中的依赖项
public class MyTestClass {
public class FakePresenter : IView {
public event Action Loaded = delegate { };
public void Render(string text) {
RenderedText = text;
}
public string RenderedText { get; private set; }
public void Load() {
Loaded();
}
}
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework() {
//Arrange
var fake = new FakePresenter();
var subject = new Presenter(fake);
var expected = "Hello Word";
//Act
fake.Load();
var actual = fake.RenderedText;
//Assert
Assert.AreEqual(expected, actual);
}
}
上述依赖项的实现公开了一个 Load()
方法来为所有订阅者引发事件,还有一个 RenderedText
属性 来捕获传递给 [=14= 的文本] 方法,以便可以根据值进行断言。
当您使用 NSubstitute 时,您必须告诉模拟视图引发一个事件。但是由于IView接口不允许你触发事件,只能添加一个事件监听器,NSubstitute做了一个workaroud,通过附加一个特殊的事件处理程序,它实际上触发了一个事件(我我不熟悉 NSubstitute,但我认为会发生这种情况):
// Code here says "attact an event handler", but NSubstitute recognizes this
// special event handler and raises the event to the "real" hanlders instead
mockView.Loaded += Raise.Event<Action>();
因此,当您离开 NSubstitute 时,您需要从假视图 "correct" 实际触发事件 class:
public class FakeView : IView
{
private string RenderedText { get; private set; }
public event Action Loaded;
public void Render(string text)
{
renderedText = text;
}
public void RaiseLoaded() {
if (Loaded != null) Loaded();
}
}
现在您可以轻松触发测试中的事件:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
FakeView view = new FakeView();
Presenter p = new Presenter(fPresenter);
view.RaiseLoaded();
Assert.That(view.RenderedText, Is.EqualTo("Hello World"));
}
我正在用 NUnit 和 NSubstiture 做一些单元测试。
我有这个class:
public class Presenter
{
public Presenter()
{
}
private readonly IView _view;
public Presenter(IView view)
{
_view = view;
this._view.Loaded += OnLoaded;
}
private void OnLoaded()
{
_view.Render("Hello Word");
}
}
我有这个界面:
public interface IView
{
event Action Loaded;
void Render(string text);
}
而且我已经使用 NSubstiture 框架进行了单元测试,如下所示:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithMockingFramework()
{
var mockView = Substitute.For<IView>();
Presenter p = new Presenter(mockView);
mockView.Loaded += Raise.Event<Action>();
mockView.Received().Render(Arg.Is<string>(s => s.Contains("Hello World")));
}
但现在我只想出于测试目的,编写相同的单元测试,但没有 NSubstiture 框架:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
IView view;
Presenter MockingVIew = new Presenter(view);
}
但是如何做到这一点?
谢谢
我这样试:
public class FakePresenter : IView
{
public event Action Loaded;
public void Render(string text)
{
}
}
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
//FakeMockingVIew = new Presenter(view);
FakePresenter fPresenter = new FakePresenter();
Presenter p = new Presenter(fPresenter);
fPresenter.Loaded += Raise.Event<Action>();
fPresenter.Received();
Assert.That(fPresenter, Is.EqualTo());
}
如果您不想再使用模拟框架,没有什么可以阻止您自己创建一个 IView
派生的 class 并将其用作测试中的依赖项
public class MyTestClass {
public class FakePresenter : IView {
public event Action Loaded = delegate { };
public void Render(string text) {
RenderedText = text;
}
public string RenderedText { get; private set; }
public void Load() {
Loaded();
}
}
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework() {
//Arrange
var fake = new FakePresenter();
var subject = new Presenter(fake);
var expected = "Hello Word";
//Act
fake.Load();
var actual = fake.RenderedText;
//Assert
Assert.AreEqual(expected, actual);
}
}
上述依赖项的实现公开了一个 Load()
方法来为所有订阅者引发事件,还有一个 RenderedText
属性 来捕获传递给 [=14= 的文本] 方法,以便可以根据值进行断言。
当您使用 NSubstitute 时,您必须告诉模拟视图引发一个事件。但是由于IView接口不允许你触发事件,只能添加一个事件监听器,NSubstitute做了一个workaroud,通过附加一个特殊的事件处理程序,它实际上触发了一个事件(我我不熟悉 NSubstitute,但我认为会发生这种情况):
// Code here says "attact an event handler", but NSubstitute recognizes this
// special event handler and raises the event to the "real" hanlders instead
mockView.Loaded += Raise.Event<Action>();
因此,当您离开 NSubstitute 时,您需要从假视图 "correct" 实际触发事件 class:
public class FakeView : IView
{
private string RenderedText { get; private set; }
public event Action Loaded;
public void Render(string text)
{
renderedText = text;
}
public void RaiseLoaded() {
if (Loaded != null) Loaded();
}
}
现在您可以轻松触发测试中的事件:
[Test]
public void ctor_WhenViewIsLoaded_CallsViewRender_WithoutMockingFramework()
{
FakeView view = new FakeView();
Presenter p = new Presenter(fPresenter);
view.RaiseLoaded();
Assert.That(view.RenderedText, Is.EqualTo("Hello World"));
}