Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 基于结构映射的依赖注入单元测试_C#_Asp.net Mvc_Unit Testing - Fatal编程技术网

C# 基于结构映射的依赖注入单元测试

C# 基于结构映射的依赖注入单元测试,c#,asp.net-mvc,unit-testing,C#,Asp.net Mvc,Unit Testing,我不熟悉MVC和IoC以及其他相关概念 我必须为一个旧项目编写单元测试用例。它使用结构映射进行依赖注入。我使用的第三方DLL公开了一些接口。现在我必须为控制器类中的方法编写单元测试用例 控制器的构造函数如下所示: HomeController(IClientData clientdata) { _clientdata = clientdata; } //The clientdata was initialized 在我的测试用例中,如何初始化控制器类和接口,如IClientData?将

我不熟悉MVC和IoC以及其他相关概念

我必须为一个旧项目编写单元测试用例。它使用结构映射进行依赖注入。我使用的第三方DLL公开了一些接口。现在我必须为控制器类中的方法编写单元测试用例

控制器的构造函数如下所示:

HomeController(IClientData clientdata)
{
    _clientdata = clientdata;
}
//The clientdata was initialized
在我的测试用例中,如何初始化控制器类和接口,如
IClientData
?将
IClientData客户端数据
传递给构造函数表示:
将类型传递为var


如何初始化/模拟
IClientData
中的数据?我不知道接口是如何在dll中实现的。

对于在单元测试中使用接口的实现,您应该使用类似的模拟框架,并且您可以设置这些接口以返回满足测试要求的默认值。在这种情况下,您将创建一个模拟来设置您希望在这个特定的预期用例中看到的值,然后将其传递给控制器

var mockClientData = new Mock<IClientData>();

mockClientData.SetupGet(data => data.MyProperty).Returns(3);
// mockClientData.Object.MyProperty now returns 3

mockClientData.Setup(data => data.MyMethod()).Returns(42);
// mockClientData.Object.MyMethod() now returns 42
// any other setup that you need done goes here

var controller = new HomeController(mockClientData.Object);

// the rest of your test as normal
var mockClientData=new Mock();
SetupGet(data=>data.MyProperty).Returns(3);
//mockClientData.Object.MyProperty现在返回3
mockClientData.Setup(data=>data.MyMethod()).Returns(42);
//mockClientData.Object.MyMethod()现在返回42
//您需要完成的任何其他设置都在此处进行
var控制器=新的HomeController(mockClientData.Object);
//其余的测试都正常进行

重要的是要注意,您不应该依赖于单元测试中依赖项的实现,因为这样您就不再测试代码单元-您正在编写集成测试。

不要试图在单元测试中模仿真实世界。单元测试应验证某个单元(此处为控制器)在给定一组先决条件的情况下是否以指定的方式运行

从您对Dan回答的评论中,我推断您似乎并不确切知道控制器在现实生活中获得的数据。如果您确切地知道前提条件必须是什么样子,并且在给定这些条件的情况下控制器应该如何工作,那么您只能编写单元测试。所以你有两个选择:

  • 通过检查构建
    IClientData
    所涉及的任何进程,尝试找出真实数据。这要求您检查DLL的源代码

  • 分析控制器的源代码。它在哪里访问
    IClientData
    ?它执行什么检查?基于此,您可以得出所需内容以及输入如何影响控制器行为的结论。然后,您可以编写一个单元测试来记录它

第二个选项意味着您创建记录“是”状态的测试,即使该状态在理论上可能与最初的预期有所不同。在retrospect中编写测试之后,您可能没有其他选择。但至少单元测试的名称和内容将使这些隐式内容非常明确。您可以向开发人员进行测试,并询问他们:“这就是控制器的行为方式。是否正确?”

无论你选择什么样的选择,你最终必须知道什么是先决条件和预期行为。一旦你知道了,你就可以通过使用
Moq
或任何其他方式来写下这个,就像丹的回答一样。对于每个测试用例,您编写一个或多个测试方法。每个方法只生成一个逻辑断言。因此,每个测试方法也只需要对
IClientData
mock进行非常有限的初始化


tl;博士

如果我使用最小起订量,我必须自己设置数据,对吗?但问题是:我的控制器从一组clientdata开始,这些clientdata是通过构造函数中传递的IClientdata初始化的。我想使用相同的初始数据。我不想自己设置它。我该怎么做呢?我当然会模拟传递给需要测试的相关函数的数据。我在这里有点困惑<代码>我的控制器从一组clientdata开始,该数据通过传入构造函数的IClientdata初始化。您要将模拟传递到构造函数中,该构造函数被设置为返回您希望看到的数据。然后使用该数据代替生产过程中传递的
IClientData
。如果您正在进行单元测试,您确实应该自己设置所有数据,以便删除任何外部依赖项或“假设”。单元测试应该是一个黑匣子,在一个你完全可以控制的受控环境中执行——这包括设置任何变量并控制它们。好的。我会再解释一遍。有一组默认数据通过IClientdata传递给构造函数。我想这是由di(这里的结构图)完成的。我想使用相同的数据初始化构造函数,然后通过模拟数据对我的函数进行单元测试。谢谢你的详细解释。我很感激。问题是,我可以模拟接口并使用它初始化控制器,但接口很大,模拟它需要很多努力。例如:有多个属于类的数据成员。我不可能嘲笑一切。所以我想改用默认实现,只使用我需要测试的函数的模拟参数。大型接口中的每个字段都是您当前编写的测试所必需的?是的。一个是必要的,其余的都取决于它。这是一个复杂的、巨大的项目。很抱歉出现了三重post-可能值得您向我们展示一个需要测试的方法,这样我们就可以指出您将如何模拟
IClientData
,这样您就可以了解它将如何运行work@Maxsteel:您可能对什么是单元测试有一些误解。一个单元测试方法应该只测试一个特定的小事情,例如控制器上的一个方法调用。Moq将为整个接口创建一个默认实现。在…上