如何在单元测试中使用全局变量?

Jan*_*n96 4 c# model-view-controller unit-testing

我需要一个在其他测试中在第一次测试中初始化的对象.为了防止代码重复,我想将我在第一次测试中创建的对象保存在全局变量中.这就是我做的:

namespace Project.WebUIV2.Tests {
    [TestClass]
    public class FilmSelectieControllerTests {
        private FilmSelectieController controller;
        [TestMethod]
        public void CanInitializeController() {
            Mock<IRepository<Voorstelling>> mockIRepository1 = new Mock<IRepository<Voorstelling>>();
            Mock<IRepository<Film>> mockIRepository2 = new Mock<IRepository<Film>>();
            Mock<IRepository<Zaal>> mockIRepository3 = new Mock<IRepository<Zaal>>();
            Film film = new Film { titel = "Film" };
            mockIRepository2.Setup(m => m.Add(film));
            var repository1 = mockIRepository1.Object;
            var repository2 = mockIRepository2.Object;
            var repository3 = mockIRepository3.Object;
            var controller = new FilmSelectieController(repository1, repository2, repository3);
            Assert.IsNotNull(controller);
            Assert.IsInstanceOfType(controller, typeof(FilmSelectieController));
            this.controller = controller;

        }

        [TestMethod]
        public void IsCreated() {
            Assert.IsInstanceOfType(controller, typeof(FilmSelectieController));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Testmethod CanInitializeController()成功,而isCreated()失败.

在第一个测试中,我创建了FilmSelectieController对象.

如何在下次测试中使用该对象?

感谢Anthony Pegram

解:

..*/
private Controller controller;

[TestInitialize]
public void Initialize() {
    var parameter = /*...test data that i need in all tests...*/
    this.controller = new Controller(parameter)
}

[TestMethod]
public void test1 {
    result = controller.FirstMethod();
    //assert something
}

[TestMethod]
public void test2 {
    result = controller.SecondMethod();
    //assert something
}
/*..
Run Code Online (Sandbox Code Playgroud)

Ant*_*ram 8

创建一个在初始化时运行的方法,并设置需要为该方法中的所有测试可用的任何对象.(该方法将在每次测试之前重新运行,因此不要指望状态持续存在.)

[TestInitialize]
public void Initialize()
{
     // your common setup code here
     this.controller = ...
}
Run Code Online (Sandbox Code Playgroud)

(TestInitialize是MS Test下的属性,在您可能使用的大多数其他测试框架下,将提供类似的属性.)

我通常会对我将在测试中使用的存根和模拟执行此操作.至于设置我正在测试的类,我通常会在测试方法本身处理它,或者将它重构为私有帮助器方法,但这只是个人偏好.如果所测试的被测试类的设置也是统一的,那么它也可以进入初始化方法.


Jer*_*vel 7

你正在混合几件事,所以让我指出这种方法有些不对劲.

隔离

一个好的单元测试是一个测试 - 最好的其他几个方面,如速度,重复性等 - 隔离.这意味着其他测试的结果或顺序不应对另一个测试的结果产生影响.良好单元测试的每个方面都同样重要,因为如果没有它们,您最好不要使用单元测试.

建立

如果您的测试依赖于某段代码才能正常工作,那么您可以在适当的范围(程序集或类初始化)中初始化它.您可以使用[Initalize][AssemblyInitialize]注释(大多数情况下您希望类初始化).

重要提示:这些是不是测试!

测试代码,而不是测试

再看看上面显示的代码.让我总结一下你做的事情:

  • 创建模拟
  • 创建Film对象
  • 设置存储库以返回电影
  • 使用注入的模拟创建控制器
  • 断言控制器已创建
  • 断言控制器属于某种类型
  • 设置实例级别变量

这有三个原因:

  • 你设置一个模拟来返回数据,但从不测试它.
  • 您创建一个控制器,然后测试它是否已创建并且它是正确的实例:无意义的操作可能是毫无意义的.
  • 您可以分配实例级别变量,该变量对其他测试没有任何影响(也不应该:查看良好单元测试的原理).

您的代码中没有任何地方在测试您的实际问题域,您只需设置测试内容.还要注意,你的模拟的一些更清晰的名称不会受到伤害.也无法保证单个类中的单元测试运行的顺序.

  • 感谢这些提示:)这是我第一次进行单元测试,这些提示非常有用。 (2认同)