Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.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# 使用Xunit进行.Net核心测试_C#_Asp.net Core_Moq_Xunit_Xunit.net - Fatal编程技术网

C# 使用Xunit进行.Net核心测试

C# 使用Xunit进行.Net核心测试,c#,asp.net-core,moq,xunit,xunit.net,C#,Asp.net Core,Moq,Xunit,Xunit.net,这是我第一次编写测试用例,我并没有陷入困境,也不知道如何继续下去 我有以下API。在下面的示例中,我有两个端点要执行测试 public class ValuesController : Controller { //This interface is used to setup dynamo db and connection to aws private IDynamoDbClientInitialization _clientAccessor; private sta

这是我第一次编写测试用例,我并没有陷入困境,也不知道如何继续下去

我有以下API。在下面的示例中,我有两个端点要执行测试

public class ValuesController : Controller
{
    //This interface is used to setup dynamo db and connection to aws
    private IDynamoDbClientInitialization _clientAccessor;
    private static string dynamoDbTable = string.Empty; 

    public ValuesController(IOptions<Dictionary<string, string>> appSettings, IDynamoDbClientInitialization clientAccessor)
    {                      
         var vals = appSettings.Value;            
         dynamoDbTable = vals["dynamoDbTable"];
        _clientAccessor = clientAccessor;
    }

    [HttpGet("api/data")]
    public async Task<List<MyModel>> GetAllData(string type, string status)
    {
        List<ScanCondition> conditions = new List<ScanCondition>();
        conditions.Add(new ScanCondition("Type", ScanOperator.Equal, type));
        conditions.Add(new ScanCondition("Status", ScanOperator.Equal, status));
        var response = await _clientAccessor.GetContext().ScanAsync<MyModel>(conditions, AWSHelperMethods.GetDynamoDbOperationConfig(dynamoDbTable)).GetRemainingAsync();
        return results.Select(x => x.UpdatedBy.ToLower()).ToList();
    }

     [HttpPost("api/save")]
    public async Task<IActionResult> SaveData([FromBody] List<MyModel> listData, string input, string name, string type)
    {
       List<MyModel> model = null; 
       foreach (var data in listData)
       {
         //populating data here
          await _clientAccessor.GetContext().SaveAsync(data, AWSHelperMethods.GetDynamoDbOperationConfig(dynamoDbTable));  
       }         

       return Ok();
    }
}       

public class DynamoDbClientInitialization : IDynamoDbClientInitialization
{
    private readonly DynamoDbClientSettings settings;
    private DynamoDBContext _awsContext;

    public DynamoDbClientInitialization(IOptions<DynamoDbClientSettings> options)
    {
        settings = options?.Value;
    }

    public DynamoDBContext GetContext()
    {         
        //Check is context already exists. If not create a new one.
        if(_awsContext != null)
        {
            return _awsContext;
        }
        else
        {                
            var creds = AWSHelperMethods.SetAwsCredentials(settings.Id, settings.Password);
            var dynamoClient = AWSHelperMethods.GetDynamoDbClient(creds, settings.Region);
            _awsContext = AWSHelperMethods.GetDynamoDbContext(dynamoClient);

            return _awsContext;
        }           
    }
}

public static class AWSHelperMethods
{
   public static BasicAWSCredentials SetAwsCredentials(string awsId, string awsPassword)
    {
        var creds = new BasicAWSCredentials(awsId, awsPassword);
        return creds;
    }

    public static AmazonDynamoDBClient GetDynamoDbClient(BasicAWSCredentials creds, RegionEndpoint awsDynamoDbRegion)
    {
        var client = new AmazonDynamoDBClient(creds, awsDynamoDbRegion);
        return client;
    }

    public static DynamoDBContext GetDynamoDbContext(AmazonDynamoDBClient client)
    {
        var context = new DynamoDBContext(client);
        return context;
    }

    public static DynamoDBOperationConfig GetDynamoDbOperationConfig(string dynamoDbTable)
    {
        DynamoDBOperationConfig config = new DynamoDBOperationConfig() { OverrideTableName = dynamoDbTable };
        return config;
    }   
 }
公共类值控制器:控制器
{
//此接口用于设置dynamo db和与aws的连接
私人Idynamodb客户化接受者;
私有静态字符串dynamoDbTable=string.Empty;
公共价值控制器(IOPS应用程序设置、IDynamodb客户化客户端接受器)
{                      
var vals=appSettings.Value;
dynamoDbTable=vals[“dynamoDbTable”];
_clientAccessor=clientAccessor;
}
[HttpGet(“api/数据”)]
公共异步任务GetAllData(字符串类型、字符串状态)
{
列表条件=新列表();
添加(新的ScanCondition(“Type”,ScanOperator.Equal,Type));
添加(新的扫描条件(“状态”,ScanOperator.Equal,Status));
var response=await_clientAccessor.GetContext().ScanAsync(条件,AWSHelperMethods.getdynamodbooperationconfig(dynamoDbTable)).GetRemainingAsync();
返回结果。选择(x=>x.UpdatedBy.ToLower()).ToList();
}
[HttpPost(“api/save”)]
公共异步任务SaveData([FromBody]列表listData,字符串输入,字符串名称,字符串类型)
{
列表模型=null;
foreach(listData中的var数据)
{
//在这里填充数据
wait_clientAccessor.GetContext().SaveAsync(数据,AWSHelperMethods.getdynamodboOperationConfig(dynamoDbTable));
}         
返回Ok();
}
}       
公共类动态客户化:IDynamodb客户化
{
专用只读DynamoDbClientSettings设置;
专用DynamoDBContext\u awsContext;
公共发电机客户化(IOPS选项)
{
设置=选项?.Value;
}
公共DynamoDBContext GetContext()
{         
//检查上下文是否已存在。如果不存在,请创建一个新上下文。
如果(_awsContext!=null)
{
返回awsContext;
}
其他的
{                
var creds=AWSHelperMethods.SetAwsCredentials(settings.Id、settings.Password);
var dynamoClient=AWSHelperMethods.GetDynamoDbClient(creds,settings.Region);
_awsContext=AWSHelperMethods.GetDynamoDbContext(dynamoClient);
返回awsContext;
}           
}
}
公共静态类AWSHelperMethods
{
公共静态基本WSCredentials设置AWSCredentials(字符串awsId、字符串awsPassword)
{
var creds=新的基本凭证(awsId、awsPassword);
回信;
}
公共静态AmazondynamodClient GetDynamoDbClient(基本凭证凭证凭证凭证、区域点AWSDynamodRegion)
{
var client=新的AmazondynamodClient(creds,AWSDynamodRegion);
返回客户;
}
公共静态DynamoDBContext GetDynamoDbContext(AmazonDynamoDBClient客户端)
{
var context=新的DynamoDBContext(客户端);
返回上下文;
}
公共静态dynamodbooperationconfig getdynamodbooperationconfig(字符串dynamoDbTable)
{
dynamodbooperationconfig=new dynamodbooperationconfig(){OverrideTableName=dynamoDbTable};
返回配置;
}   
}
下面是我添加的xunit项目。在这里,我使用MOQ来MOQ我的aws连接和其他连接。以下是针对该准则的评论中的问题

public class DataTest
{

    [Fact]
    public void PassingTest()
    {
       //Arrange
       var dynamoDbTable = "someValue";

       //Trying to moq IOptions
       var moqOp = new Mock<IOptions<Dictionary<string, string>>>();

       //Create an instance to hold desired values
       var vals = new Dictionary<string, string>();

       //Set expected value
       vals["dynamoDbTable"] = dynamoDbTable;

       //Setup dependency behavior
       moqOp.Setup(_ => _.Value).Returns(vals);

       //Trying to moq my connection  
       var moqDb = new Mock<IDynamoDbClientInitialization>();

       //Fake data
       List<MyModel> data = new List<MyModel>()
      { 
        //populate as needed
       };

     moqDb
     .Setup(_ => _.GetContext().ScanAsync<MyModel>
     (It.IsAny<List<ScanCondition>>(), AWSHelperMethods.GetDynamoDbOperationConfig(dynamoDbTable)).GetRemainingAsync())
.ReturnsAsync(data);

      ValuesController controller = new ValuesController(moqOp.Object, 
       moqDb.Object);

      var actual =  controller.GetAllData();
    }       
}
公共类数据测试
{
[事实]
public void PassingTest()
{
//安排
var dynamoDbTable=“someValue”;
//试着减少吸烟
var moqOp=new Mock();
//创建一个实例来保存所需的值
var vals=新字典();
//设置期望值
VAL[“发电机表”]=发电机表;
//设置依赖行为
moqOp.Setup(=>qop.Value).Returns(VAL);
//正在尝试删除我的连接
var moqDb=new Mock();
//假数据
列表数据=新列表()
{ 
//根据需要填充
};
moqDb
.Setup(=>\u0.GetContext().ScanAsync
(It.IsAny(),AWSHelperMethods.getdynamodboOperationConfig(dynamoDbTable)).GetRemainingAsync())
.ReturnsAsync(数据);
ValuesController=新的ValuesController(moqOp.Object,
moqDb.对象);
var actual=controller.GetAllData();
}       
}
上面我得到的错误如下: 表达式树不能包含使用可选参数的调用或调用

这是在线的

.Setup(_ => _.GetContext().ScanAsync<MyModel>
 (It.IsAny<List<ScanCondition>>(), AWSHelperMethods.GetDynamoDbOperationConfig(dynamoDbTable)).GetRemainingAsync())
.Setup(\u=>\ uu.GetContext().ScanAsync
(It.IsAny(),AWSHelperMethods.getdynamodboOperationConfig(dynamoDbTable)).GetRemainingAsync())
有人能帮忙解决吗

---更新---

公共接口IDynamoDbManager
{
任务GetAsync(IEnumerable条件);
任务SaveAsync(T项);
}
表达式树不能包含使用 可选参数

您正在尝试“调用”尚未设置GetContext()的上的ScanAsync方法。要解决此问题,必须在尝试设置ScanAsync()之前为GetContext()设置返回值


这段代码很难测试,所以让我们重构它

您必须将对
\u clientAccessor.GetContext()
的直接调用更改为对IDynamoDBContext的注入。 dynamodb客户化没有意义,因为可以很容易地用IAmazonDynamoDb替代。要消除冗长的配置读取代码行,请使用

services.AddAWSService<IAmazonDynamoDB>();
services.AddAWSService();
对DynamoDb的所有调用都应该封装在一个单独的类中,该类称为,DynamoDbManager

公共类DynamoDbManager:DynamoDBContext,IDynamoDbManager其中T:class
{
专用dynamodbooperationconfig _config;
公共DynamoDbManager(IAmazonDynamoDB客户端,字符串ta)
services.AddAWSService<IAmazonDynamoDB>();
public class DynamoDbManager<T> : DynamoDBContext, IDynamoDbManager<T> where T : class
    {
        private DynamoDBOperationConfig _config;

        public DynamoDbManager(IAmazonDynamoDB client, string tableName): base(client)
        {
            _config = new DynamoDBOperationConfig()
            {
                OverrideTableName = tableName
            };
        }

        public Task<List<T>> GetAsync(IEnumerable<ScanCondition> conditions)
        {
            return ScanAsync<T>(conditions, _config).GetRemainingAsync();
        }

        public Task SaveAsync(T item)
        {
            return base.SaveAsync(item, _config);
        }
    }
public class ValuesController : Controller
    {
        private readonly IDynamoDbManager<MyModel> _dynamoDbManager;
        //This interface is used to setup dynamo db and connection to aws
        private static string dynamoDbTable = string.Empty;

        public ValuesController(IOptions<Dictionary<string, string>> appSettings, IDynamoDbManager<MyModel> dynamoDbManager)
        {
            _dynamoDbManager = dynamoDbManager;
            var vals = appSettings.Value;
            dynamoDbTable = vals["dynamoDbTable"];
        }

        [HttpGet("api/data")]
        public async Task<IActionResult> GetAllData(string type, string status)
        {
            var conditions = new List<ScanCondition>
            {
                new ScanCondition("Type", ScanOperator.Equal, type),
                new ScanCondition("Status", ScanOperator.Equal, status)
            };
            var result = await _dynamoDbManager.GetAsync(conditions);
            var response = result.Select(_ => _.UpdatedBy.ToLower()).ToList();
            return Ok(response);
        }

        [HttpPost("api/save")]
        public async Task<IActionResult> SaveData([FromBody] List<MyModel> listData, string input, string name, string type)
        {
            foreach (var data in listData)
            {
                //populating data here
                await _dynamoDbManager.SaveAsync(data);
            }
            return Ok();
        }
    }
public class ValuesControllerTests
    {
        private Mock<IDynamoDbManager<MyModel>> _dbManager;
        private ValuesController _valuesController;

        public ValuesControllerTests()
        {
            var mockRepository = new MockRepository(MockBehavior.Loose);
            _dbManager = mockRepository.Create<IDynamoDbManager<MyModel>>();
            var options = new OptionsWrapper<Dictionary<string, string>>(new Dictionary<string, string>()
            {
                {"dynamoDbTable", nameof(MyModel) }
            });
            _valuesController = new ValuesController(options, _dbManager.Object);

        }

        [Fact]
        public async Task GetAllData_ShouldSelectUpdateByInLowerCase()
        {
            //
            var searchResult = new List<MyModel>()
            {
                new MyModel() {UpdatedBy = "UpdatedBy1"}
            };
            _dbManager
                .Setup(_ => _.GetAsync(It.Is<List<ScanCondition>>(list => list.Count == 2)))
                .ReturnsAsync(searchResult);

            //

            var result = await _valuesController.GetAllData("typeValue", "statusValue");

            //
            var okResult = result as OkObjectResult;
            Assert.NotNull(okResult);
            var values = okResult.Value as List<string>;
            Assert.Contains("updatedby1", values);
        }

        [Fact]
        public async Task SaveData_ShouldCallSaveForAllRequestedData()
        {
            //
            var listData = new List<MyModel>()
            {
                new MyModel(),
                new MyModel(),
                new MyModel()
            };
            _dbManager
                .Setup(_ => _.SaveAsync(It.IsAny<MyModel>()))
                .Returns(Task.CompletedTask);

            //

            var result = await _valuesController.SaveData(listData, "","", "");

            //
            _dbManager.Verify(_ => _.SaveAsync(It.IsAny<MyModel>()), Times.Exactly(3));
        }
    }