Пакетное тестирование SendAll ServiceStack - PullRequest
0 голосов
/ 27 января 2019

Я получаю сообщение об ошибке на SendAll в юнит-тесте

Это прекрасно работает ...

 using (var service = HostContext.ResolveService<DeviceService>(authenticatedRequest))
                    {
                        service.Put(new AddConfig { ConfigName = key.KeyName, ConfigValue = key.Value, DeviceId = 0 });
                    }}

ServiceStack.WebServiceException: «Операция« AddConfig [] »не существует для этой службы»

  //DeviceConfig
        /// <summary>
        /// To insert new Config
        /// </summary>
        /// <returns> New row Id or -1 on error</returns>
        public long Any(AddConfig request)
        {
            try
            {
                //convert request to model
                var perm = request.ConvertTo<DeviceConfig>();
                //log user
                perm.AuditUserId = UserAuth.Id;
                //insert data
                var insert = Db.Insert(perm, selectIdentity:true);
                //log inserted data
                LogInfo(typeof(DeviceConfig), perm, LogAction.Insert);
                return insert;
            }
            //on error log error and data
            catch (Exception e)
            {
                Log.Error(e);
            }
            return -1;
        }

   [Route("/Config", "PUT")]
    public class AddConfig : IReturn<long>
    {
        public int DeviceId { get; set; }
        public string ConfigName { get; set; }
        public string ConfigValue { get; set; }
    }

public const string TestingUrl = "http://localhost:5123/";

    public void DeviceX400Test(string deviceTemaplateFile)
    {
        //Resolve auto-wired service
        WireUpService<DeviceService>();

        var requests = new[]
        {
            new AddConfig { ConfigName = "Foo" },
            new AddConfig { ConfigName = "Bar" },
            new AddConfig { ConfigName = "Baz" },
        };
        var client = new JsonServiceClient(TestingUrl);
        var deviceConfigs = client.SendAll(requests);
    }

MY ServiceBase для модульного тестирования, который создается из моего файла .netcore appsettings.Json

 public abstract class ServiceTestBase: IDisposable
    {
        //private readonly ServiceStackHost appHost;
        public BasicRequest authenticatedRequest;
        public const string TestingUrl = "http://localhost:5123/";
        public SeflHostedAppHost apphost;
        public ServiceTestBase()
        {
            var licenseKeyText = "********************************";
            Licensing.RegisterLicense(licenseKeyText);

            apphost = (SeflHostedAppHost) new SeflHostedAppHost()
                .Init()
                .Start(TestingUrl);
            //regsiter a test user
            apphost.Container.Register<IAuthSession>(c => new AuthUserSession { FirstName = "test", IsAuthenticated = true }); 
        }

        public void WireUpService<T>() where T : class
        {
            //var service = apphost.Container.Resolve<T>();  //Resolve auto-wired service
            apphost.Container.AddTransient<T>();

            authenticatedRequest = new BasicRequest
            {
                Items = {
                    [Keywords.Session] = new AuthUserSession { FirstName = "test" , UserAuthId="1", IsAuthenticated = true}
                }
            };
        }

        public virtual void Dispose()
        {
            apphost.Dispose();
        }
    }

    //Create your ServiceStack AppHost with only the dependencies your tests need
    /// <summary>
    /// This class may need updates to match what is in the mvc.service apphost.cs
    /// </summary>
    public class SeflHostedAppHost : AppSelfHostBase
    {
        public IConfigurationRoot Configuration { get; set; }

        public SeflHostedAppHost() : base("Customer REST Example", typeof(StartupService).Assembly) { }

        public override void Configure(Container container)
        {
            var file = Path.GetFullPath(@"../../../../cbw.services");
            var builder = new ConfigurationBuilder().SetBasePath(file).AddJsonFile("appsettings.json").AddJsonFile("appsettings.LocalSQLServer.json", optional: true);
            Configuration = builder.Build();
            var sqlString = Configuration["ConnectionString"];

            RegisterServiceStack();
            //container.Register<ServiceStack.Data.IDbConnectionFactory>(new OrmLiteConnectionFactory(sqlString,SqlServerDialect.Provider));
            container.Register<IDbConnectionFactory>(new OrmLiteConnectionFactory(":memory:", SqliteDialect.Provider));
            container.RegisterAutoWired<DatabaseInitService>();
            var service = container.Resolve<DatabaseInitService>();

            container.Register<IAuthRepository>(c =>
                new MyOrmLiteAuthRepository(c.Resolve<IDbConnectionFactory>())
                {
                    UseDistinctRoleTables = true,
                });
            container.Resolve<IAuthRepository>().InitSchema();
            var authRepo = (OrmLiteAuthRepository)container.Resolve<IAuthRepository>();

            service.ResetDatabase();
            SessionService.ResetUsers(authRepo);
            service.InitializeTablesAndData();

            //Logging
            LogManager.LogFactory = new SerilogFactory(new LoggerConfiguration()
                .ReadFrom.Configuration(Configuration)
                .Destructure.UsingAttributes()
                .CreateLogger());
            Serilog.Debugging.SelfLog.Enable(msg => Debug.WriteLine(msg));
            Serilog.Debugging.SelfLog.Enable(Console.Error);

            ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
            //ILog Log = LogManager.GetLogger(typeof(StartupService));

            log.InfoFormat("Applicaiton Starting {Date}", DateTime.Now);
        }

        public void RegisterServiceStack()
        {
            var licenseKeyText = "****************************";
            Licensing.RegisterLicense(licenseKeyText);
        }

    }

My Xunit Test

 public class DeviceTemplateTest : ServiceTestBase
    {

        //Post Data
        //Device Sends State.XML

        [Theory]
        [InlineData("C:\\DeviceTemplate.txt")]
        public void DeviceX400Test(string deviceTemaplateFile)
        {
            //Resolve auto-wired service
            WireUpService<DeviceService>();

            var parser = new FileIniDataParser();
            IniData data = parser.ReadFile(deviceTemaplateFile);

            List<AddConfig> batch = new List<AddConfig>();
            //Iterate through all the sections
            foreach (SectionData section in data.Sections)
            {
                Console.WriteLine("[" + section.SectionName + "]");

                //Iterate through all the keys in the current section
                //printing the values
                foreach (KeyData key in section.Keys)
                {
                    batch.Add(new AddConfig { ConfigName = key.KeyName, ConfigValue = key.Value, DeviceId = 0 });
                    //    using (var service = HostContext.ResolveService<DeviceService>(authenticatedRequest))
                    //{
                    //    service.Any(new AddConfig { ConfigName = key.KeyName, ConfigValue = key.Value, DeviceId = 0 });
                    //}
                }
            }

            var client = new JsonServiceClient(TestingUrl);
            var deviceConfigs = client.SendAll(batch.ToArray());
        }

    }

1 Ответ

0 голосов
/ 27 января 2019

Во-первых, вы не должны никогда не возвращать типы значений в Службах , ваш запрос DTO говорит, что он возвращает DeviceConfig Тип ответа DTO:

public class AddConfig : IReturn<DeviceConfig> { ... }

, который должен возвращать ваш Сервис вместо.

Мне неясно, как это может работать или компилироваться:

using (var service = HostContext.ResolveService<DeviceService>(authenticatedRequest))
{
    service.SendAll(new AddConfig { 
         ConfigName = key.KeyName, ConfigValue = key.Value, DeviceId = 0 
    });
}

Поскольку он вызывает методы класса обслуживания DeviceService напрямую, а SendAll() метод в Service class (или в вашем примере), вы вместо этого использовали Service Gateway ?

Я не могу сказать, в чем проблема, не видя полного исходного кода и не имея возможностичтобы воспроизвести проблему, но похоже, что AddConfig не распознается как служба, она отображается на странице /metadata?Если нет, у вас есть класс, который наследует Service?

В противном случае, если вы сможете опубликовать минимальное повторение на GitHub, я смогу определить проблему.

...