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



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

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));
        }
    }
}

测试方法CanInitializeController()成功,而isCreated()失败。

在第一个测试中,我创建了FilmSelectionController对象。

在接下来的测试中如何使用该对象?

感谢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
}
/*..

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

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

TestInitialize是MS测试下的属性,在您可能使用的大多数其他测试框架下都可以使用类似的属性。)

我通常会为测试中使用的存根和mock做这件事。至于设置我实际测试的类,我通常会在测试方法本身中处理它,或者将它重构为一个私有的助手方法,但这只是个人的偏好。如果测试中的类的设置对于所有测试也是统一的,那么它也可以进入初始化方法。

您混合了一些东西,所以让我指出这种方法的一些错误。

隔离

一个好的单元测试是一个与速度、重复性等其他方面隔离的测试。这意味着其他测试的结果或顺序不应影响另一项测试的结果。一个好的单元测试的每一个方面都同样重要,因为没有它们,你可能一开始就不使用单元测试。

设置

如果您的测试依赖于某个代码片段来正常工作,那么您可以在适当的范围内对此进行初始化(程序集或类初始化)。为此,您使用[Initalize][AssemblyInitialize]注释(大多数情况下,您希望初始化类)。

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

测试代码,而不是测试

再看一下上面显示的代码。让我总结一下你的做法:

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

这是错误的,原因有三:

  • 您设置了一个mock来返回数据,但从不测试它
  • 您创建了一个控制器,然后测试它是否已创建,以及它是否具有正确的实例:就像毫无意义的操作一样毫无意义
  • 您分配的实例级变量不会对其他测试产生任何影响(也不应该:请参阅好的单元测试的原则)

在你的代码中,没有任何地方是在测试你的实际问题域,你只是在设置测试的东西。还要注意,为你的mock取一些更清晰的名字不会有什么坏处。也不能保证在单个类中运行单元测试的顺序。

我认为您必须使用装饰器[TestInitialize]
这用于在执行所有[TestMethods]之前初始化测试序列。

最新更新