gpt4 book ai didi

asp.net - 这是测试演示者的正确方法吗

转载 作者:行者123 更新时间:2023-11-28 20:45:59 25 4
gpt4 key购买 nike

我正在使用网络表单和 MVP 模式在三层架构中创建一个购物网站。我还决定在演示者类内部进行验证和类型转换。对于测试框架,我使用 NUnit,对于我的模拟,我使用 NSubstitude。这是我的类别模型类:

    //we're doing Dependency injection here.
public abstract class BaseRepository
{
EntityContext context;
public BaseRepository()
{
context = new EntityContext();
}
public EntityContext Context
{
get { return context; }
}
}
public class CategoryRepository : BaseRepository
{
public int Add(long id, string name)
{
Category cat = new Category();
cat.Id = id;
cat.Name = name;
Context.Category.Add(cat);
Context.SaveChanges();
}
}

这是类别展示者:

    public class CategoryPresenter : BasePresenter //has nothing but a dependency property to Logger
{
BaseRepository _model;
IView _view;
public CategoryPresenter(IView view)
{
_model = new CategoryRepository();
_view = view;
}
public void Add()
{
//havn't passed the tests yet since i'm not sure if i'm on the correct path.
//whatever validation, loggin and type casting will go here.
_model.Add(_view.CategoryId, _view.CategoryName);
}
}

这是演示者的测试类:

    [Test]
public void Add_NullId_ThrowException()
{
_view.CategoryId.Returns(p => null);
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_EmptyId_ThrowException()
{
_view.CategoryId.Returns(p => "");
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_SpaceOnlyId_ThrowException()
{
_view.CategoryId.Returns(p => " ");
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_InvalidLowBoundId_ThrowException()
{
_view.CategoryId.Returns(p => "-1");
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_InvalidHighBoundId_ThrowException()
{
_view.CategoryId.Returns(p => long.MaxValue.ToString() + "1");
_view.CategoryName.Returns(p => "test");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}

[Test]
public void Add_EmptyName_ThrowException()
{
_view.CategoryId.Returns(p => "1");
_view.CategoryName.Returns(p => "");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_NullName_ThrowException()
{
_view.CategoryId.Returns(p => "1");
_view.CategoryName.Returns(p => null);
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_SpaceOnlyName_ThrowException()
{
_view.CategoryId.Returns(p => "1");
_view.CategoryName.Returns(p => " ");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}
[Test]
public void Add_NumberOnlyName_ThrowException()
{
_view.CategoryId.Returns(p => "1");
_view.CategoryName.Returns(p => "123");
Assert.Throws(typeof(InvalidOperationException), _presenter.Add());
}

我测试正确吗?我的意思是这是测试类应该是什么样子?我错过了什么吗?这太多了吗?像“你不需要测试空虚”或与我的测试或代码相关的任何其他问题?如果您发现我的整个代码和/或架构中有任何错误,请您纠正我,我将不胜感激。谢谢!

更新: IView 由.aspx 页面继承。在后面的代码中,我只是从用户按下按钮触发的点击事件内部调用演示者方法。至于内存,我还没有走那么远。只是停留在 TDD 上。

最佳答案

我将从应用层(演示者所在的位置)移除验证逻辑并将其提取到域层(存储库所在的位置)。

然后不要在演示者那里进行验证,而是让演示者调用必要的验证器。

对于呈现器的单元测试,您向呈现器提供验证器模拟对象并验证是否为数据调用了正确的验证方法。

所以你必须测试两件事:1) 测试演示者是否使用 View 中的数据调用验证器2) 自己测试验证器

测试可能看起来像这样:

对于演示者(类 CategoryPresenterTests):

[Test]
public void Add_CallsTheValidatorWithDataFromTheView()
{
_viewMock.CategoryId.Returns(p => "id");
_viewMock.CategoryName.Returns(p => "name");

_presenter.Add();

_categoryValidatorMock.Verify(x=>x.Validate("id", "name"), Times.Once);
}

[Test]
public void Add_ForwardsValidationExceptions()
{
_viewMock.CategoryId.Returns(p => "id");
_viewMock.CategoryName.Returns(p => "name");

_categoryValidatorMock.Setup(x=>x.Validate(...)).Throws<ValidationException>();

Assert.Throws<ValidationException>(() => _presenter.Add());
}

请注意,我们不关心来自 View 的具体输入,只关心使用来自 View 的确切数据调用验证器并将结果(在本例中为异常或无异常)传回。

对于验证器(类 CategoryValidatorTests。基本上所有当前的测试都放在这里):

[Test]
public void NullId_ThrowsException() {
string id = null;
string name = "test";
Assert.Throws<ValidationException>(() => _validator.Validate(id, name));
}

请注意,我不知道 NSubstitutes 语法,所以上面是伪代码..希望你能破译它:)

除此之外,我不会在演示者中创建存储库,而是通过构造函数注入(inject)它们的接口(interface)(就像您对 IView 所做的那样)。然后提供模拟对象,并与验证器一样,验证演示者是否正确调用了它们。

以上所有内容都应该允许您在演示者之外重用验证逻辑,并且它会从演示者那里减少一些复杂性,让他们更多地专注于他们在模型和 View 之间进行调解和处理工作流的实际目的。

关于asp.net - 这是测试演示者的正确方法吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9946380/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com