我在写我的第一MSpec规范和我想要一些指导。我离开前在"待定"状态,但是上下文填写。是否有任何改进的地方?

对于参考,这是故事和第一种情况:

Story: "Blog admin logs in to the system"

As a blog writer
I want to be able to log in to my blog
So that I can write posts and administer my blog

Scenario: "Logs in from the login page"

Given the user enters in correct credentials for a user in the system
When the user clicks the "Login" button
Then log the user in and redirect to the admin panel with a message 
stating that he logged in correctly

和MSpec代码(一些零部件剪),请注意,我不得不到别的MSpec It 委托由于冲突带 Moq.It:

using MoqIt = Moq.It;
using ThenIt = Machine.Specifications.It;

[Subject("User tries logging in")]
public class When_user_enters_valid_credentials : With_user_existing_in_membership
{
    protected static ActionResult result;

    Because of = () =>
    {
        result = loginController.Login(validUsername, validPassword);
    };

    ThenIt should_log_the_user_in;
    ThenIt should_redirect_the_user_to_the_admin_panel;
    ThenIt should_show_message_confirming_successful_login;
}

public abstract class With_user_existing_in_membership
{
    protected static Mock<ISiteMembership> membershipMock;
    protected static string validUsername;
    protected static string validPassword;
    protected static LoginController loginController;

    Establish context =()=>
    {
        membershipMock = new Mock<ISiteMembership>();
        validUsername = "ValidUsername";
        validPassword = "ValidPassword";
        //make sure it's treated as valid usernames and password
        membershipMock
            .Setup<bool>(m => m.Validate(
                MoqIt.Is<string>(s => s == validUsername), 
                MoqIt.Is<string>(s => s == validPassword)))
            .Returns(true);
        loginController = new LoginController(membershipMock.Object);
    };
}
有帮助吗?

解决方案

上下文看起来很好。我喜欢你的方式解决冲突 It 用别名。我认为,最低采购量的别名以改善。考虑什么一句话-等。例如, Param.Is<T>Value.Is<T>.

一些注意到,代码段,那么整个规范改写在底部。

该方案是你的 Subject

主题可以是方案的故事。另外,它得到的呈现你的测试运行报告(特别好的HTML报告)。

[Subject("Login Page")]

不要把时间浪费在"与"命名的基类

MSpec的创造者,亚伦*詹森 已经恢复 从使用"与"法完全。下流的名字没有显示任何报告,因此避免花费的时间创造一个有意义的名称。

public abstract class MembershipContext

该给你的规格的类名称

名称的具体规格的类后给出在你的故事。特别是由于基类的名字没有报告任何地方,你可能会失去一半你的上下文中报告!你也应该避免把该系统名称下测试,在上下文类名称。这使得环境友好的重构系统进行测试。

public class When_an_existing_user_enters_valid_credentials

基类规范应该只包含一般性的初始化

和往往是不必要的。他们导致的分离的安排和行动的阶段。使用的基类公共场初始化,如设置嘲笑的依赖关系。但是,你不应该模拟行为在基类。你不应该把具体情况的信息的基类。在你的例子中,用户名和密码。这种方式,可以创建一个二背景下与无效的全权证书。

Establish context = () =>
{
    membership = new Mock<ISiteMembership>();
    loginController = new LoginController(membership.Object);
};

领域中的具体规格的类应该是私有的

它减少了"仪式"的语言,在你的测试。你应该把他们放下所有的MSpec特定的代表,因为这些零部件的规格说大多数的故事。

static ActionResult result;

规范改革

规范这是一个很好的例子,建立一个全球背景 MembershipContext 和继承它在下文具体规格(因此,额外 Establish).

[Subject("Login Page")]
public class When_an_existing_user_enters_valid_credentials : MembershipContext 
{
    Establish context = () =>
    {
        membership
            .Setup<bool>(m => m.Validate(
                Param.Is<string>(s => s == username), 
                Param.Is<string>(s => s == password)))
            .Returns(true);
    };

    Because of = () => result = loginController.Login(username, password);

    It should_log_the_user_in;
    It should_redirect_the_user_to_the_admin_panel;
    It should_show_message_confirming_successful_login;

    static ActionResult result;
    const string username = "username";
    const string password = "password";
}

public abstract class MembershipContext 
{
    Establish context = () =>
    {
        membership = new Mock<ISiteMembership>();
        loginController = new LoginController(membership.Object);
    };

    protected static Mock<ISiteMembership> membership;
    protected static LoginController loginController;
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top