小编Lud*_*c C的帖子

Delphi:如何以编程方式创建泛型类型?

如何在Delphi中动态构造泛型类型?

让我解释

如果我有一个界面IMyInterface<T>,

我想动态分配泛型T参数并以某种方式获取对该类型的引用.

function GetInterfaced(aType : PTypeInfo) : TRttiType
begin
    Result := ???
    // I want to return TypeInfo(IMyInterface<aType>);
    // or a RttiType that corresponds to TRttiContext.GetType(IMyInterface<aType>)
end;
Run Code Online (Sandbox Code Playgroud)

如何动态构建此泛型类型?

一个限制,我不能使用

function GetInterfaced<T> : TRttiType
begin
    Result := TrttiContext.Create.GetType(TypeInfo(IMyInterface<T>))
end;
Run Code Online (Sandbox Code Playgroud)

编辑

我正在尝试使用Stefan的Spring4d容器创建一个类型来解析组件

例如 :

function ResolveLookup(aModelType : PTypeInfo) : TObject
var aLookupType : PTypeInfo
begin
    aLookupType := SomehowGetTypeOf(ILookup<aModelType>);
    Result := FContainer.Resolve(aLookupType).AsObject;     
end;
Run Code Online (Sandbox Code Playgroud)

我真正的用例是我定义了一组模型(

TAssociate = class(TModel)
TUser = class(TModel)
TMandate = class(TModel)
Run Code Online (Sandbox Code Playgroud)

我还为他们定义了"查找"视图:

TAssociateLookup = …
Run Code Online (Sandbox Code Playgroud)

delphi generics dynamic rtti

3
推荐指数
1
解决办法
502
查看次数

如何用DUnit模拟Spring4D事件

我正在努力用DUnit成功模拟一个Spring4d事件.

事实上,我更嘲笑一个模拟返回模拟事件...

这是基本结构.

TMyObject --EventContainer--> TMock<IEventContainer> --Event--> TMock<IEvent>
Run Code Online (Sandbox Code Playgroud)

TMyObject有一个属性EventContainer:IEventContainer

IEventContainer有一个属性Event:IMyEvent

我想嘲笑

MyObject.EventContainer.Event.Add
Run Code Online (Sandbox Code Playgroud)

我测试了我能想到的每种可能性.我得到AV或无效的演员.我把源代码放在下面.如果有人能帮助我让这个工作真的很漂亮!

program Project2;

{$APPTYPE CONSOLE}
{$R *.res}

uses
    System.SysUtils,
    DUnitTestRunner,
    Spring.Events,
    Spring,
    Classes,
    TestFramework,
    Delphi.Mocks;
    //Unit1 in 'Unit1.pas';

type

{$M+}
    IMyEvent = interface(IEvent<TNotifyEvent>)
        procedure Add(const handler: TMethod);
    end;
{$M-}
{$M+}

    IMyEventMock = interface(IMyEvent)
        procedure Add(const handler: TMethod);
    end;
{$M-}
{$M+}

    IEventContainer = interface(IInterface)
        function GetEvent: IMyEvent;
        procedure SetEvent(const Value: IMyEvent);
        property Event: IMyEvent
            read GetEvent
            write SetEvent;
    end;
{$M-}
{$M+}

    ITestEventContainer = interface(IEventContainer)
        function GetEvent: TMock<IMyEvent>;
        procedure SetEvent(const …
Run Code Online (Sandbox Code Playgroud)

delphi unit-testing dunit spring4d

2
推荐指数
1
解决办法
352
查看次数

Delphi:如何将 Format() 与运行时构建的 TVarRec 数组一起使用?

我正在为存储库构建 SQL 查询构建器。此构建器将查找查询的所有必需字段并创建 SQL 文本。为此,我正在使用 Format() 过程。但是,我在运行时无法创建必须传递给 Format 过程的 TVarRec 数组。

使用 Format('%s, %s', ['AString', 'AnotherString']);` 等常量构建这个数组很容易。但是我们必须如何在运行时创建它呢?

这是我的方法的简化版本:

procedure BuildString;
begin

    FStrings := TStringList.Create;

    FStrings.Add('String 1');
    FStrings.Add('String 2');
    FStrings.Add('String 3');

    FFormatString := '%0:s, %1:s, %2:s';

    SetLength(FFormatStringParams, FStrings.Count);

    for I := 0 to FStrings.Count - 1 do
    begin
      aString := FStrings.Strings[I];
      FFormatStringParams[I].VString := Addr(aString);
    end;

    ShowMessage(Format(FFormatString, FFormatStringParams));

end;
Run Code Online (Sandbox Code Playgroud)

但是当我运行它时,我收到错误“格式 '%0:s, %1:s, %2:s' 无效或与参数不兼容”

我知道我错误地构建了必须传递给 Format 过程的 TVarRec 数组。任何人都可以帮助我吗?

谢谢你。

delphi pointers string-formatting

2
推荐指数
1
解决办法
941
查看次数

如何使用browserify捆绑多个javascript库?

我正在尝试在浏览器中使用Browerifiy,如果我使用独立选项它会暴露一个模块.我不想这样做.网站和文档似乎在我实际编译代码的任何地方都被切断了.没有人说过如何在浏览器属性中实际使用代码.

我有一个笨拙的任务:

browserify: {
      standalone: {
        src: [ '<%= yeoman.server %>/shared-components/**/*.js' ],
        dest: '<%= yeoman.client %>/app/js/browserifed-shared-code.js',
        /* Commented out, zero documentation on this. Can only expose one module it seems.
        options: {
          browserifyOptions: {
            standalone: 'Utility' //Unable to say '**/*' error :-/
          }
        }
        */
      },
Run Code Online (Sandbox Code Playgroud)

这似乎工作,它使这样的文件:

(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';

var UrlController = function(){};

UrlController.test = function () {
    return …
Run Code Online (Sandbox Code Playgroud)

javascript node.js npm browserify gruntjs

2
推荐指数
1
解决办法
2534
查看次数

德尔福单元测试:为CUT编写一个简单的间谍

我在寻找一种方式来轻松简洁地写为Delphi下DUnitX测试框架间谍.

在过去,我使用非常难看的方式:

[TestFixture]
Test = class(TObject)
public
  [test]
  procedure Test1;
end;

TMyClass = class(TObject)
protected
  procedure MyProcedure; virtual;
end;

TMyTestClass = class(TMyClass)
protected
  fMyProcedureCalled : Boolean;
  procedure MyProcedure; override;
end

procedure TMyTestClass.MyProcedure;
begin
   fMyProcedureCalled := true;
   inherited;
end;

procedure Test.Test1;
var aObj : TMyTestClass;
begin
   TMyTestClass.Create;
   Assert.IsTrue(aObj.fMyProcedureCalled);
end;
Run Code Online (Sandbox Code Playgroud)

所有这些代码都用于检查是否调用了一个过程.那太冗长了!

有没有办法写一个可以帮助我减少代码的间谍?

delphi unit-testing dunit spy dunitx

2
推荐指数
1
解决办法
265
查看次数

Moq单元测试:Moq.Proxy.CastleProxyFactory上的System.TypeInitializationException

我正在使用Moq作为我的单元测试的模拟库.

它似乎很难找到Castle Windsor库,因为它给了我这个错误:

System.TypeInitializationException : Une exception a été levée par l'initialiseur de type pour 'Moq.Mock`1'.
  ----> System.TypeInitializationException : Une exception a été levée par l'initialiseur de type pour 'Moq.Proxy.CastleProxyFactory'.
  ----> System.IO.FileNotFoundException : Impossible de charger le fichier ou l'assembly 'Castle.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc' ou une de ses dépendances. Le fichier spécifié est introuvable.
   à Moq.Mock`1.<InitializeInstance>b__24_0()
   à Moq.PexProtector.Invoke(Action action)
   à Moq.Mock`1.InitializeInstance()
   à Moq.Mock`1.OnGetObject()
   à Moq.Mock.GetObject()
   à Moq.Mock.get_Object()
   à Moq.Mock`1.get_Object()
   à TecLib.Common.Tests.Infrastructure.CqrsRepositoryBaseTest.SetUp() dans C:\Users\Ludovic\Documents\Visual Studio 2015\Projects\TEC2\TecLib.Common.Tests\Infrastructure\CqrsRepositoryBaseTest.cs:ligne 38
--TypeInitializationException
   à Moq.Proxy.CastleProxyFactory..ctor()
   à …
Run Code Online (Sandbox Code Playgroud)

c# castle-windsor moq

2
推荐指数
1
解决办法
4286
查看次数

Delphi - 测试是否将事件分配给方法,但不覆盖每个委托类型

我必须在Delphi中对某些表单进行单元测试.我的老板要我编写测试来检查是否分配了事件.有太多我们必须对它们进行一些检查.

例如,我想检查一下

TMyForm.OnCreate = TMyForm.FormCreate.
Run Code Online (Sandbox Code Playgroud)

为此,我写道:

function TFMaitreTest.SameMethod(const Method1, Method2: TNotifyEvent; msg : string = ''): boolean;
begin
Assert.IsTrue(TEqualityComparer<TNotifyEvent>.Default.Equals(Method1, Method2), msg);
end;
Run Code Online (Sandbox Code Playgroud)

但是使用这种方式,我必须覆盖SameMethod每种事件委托:TNotifyEvent,TDataSetEvent,...

然后我想到使用泛型,如下:

function TFMaitreTest.SameMethod<T>(const Method1, Method2: T; msg : string = ''): boolean;
Run Code Online (Sandbox Code Playgroud)

但这不编译.TEqualityComparer需要一些通用约束,但不能为对象的过程定义通用约束.使用TMethod约束也不起作用.也许这里有办法,但我还没找到.

然后,我想到了使用Rtti改变方法.我想比较使用Rtti的方法,但为此,我必须知道带字符串的方法的名称.

RttiType.GetMethod(methodName)
Run Code Online (Sandbox Code Playgroud)

这里methodName是一个纯粹的字符串.如果我们重构并methodName成为MyMethod,我们有点搞砸了,必须在每个字符串使用的地方手动检查.我们希望编译时错误.它不容易出错.

C#具有lambda表达式的概念,它对于这些场景非常强大:

请参阅使用表达式获取方法的名称

如果将事件属性分配给特定过程,而不必为每种事件类型编写方法,我如何编写更通用的测试方法?

谢谢您的帮助.

delphi generics unit-testing

1
推荐指数
1
解决办法
291
查看次数

Delphi Rtti Get Property - 为什么会导致AV?

我正在尝试编写一个spec实用程序库.

规范之一是TExpressionSpecification.基本上,它通过评估内部TExpression来实现规范模式.

其中一个TExpression是TPropertyExpression.它只是一个表达式,通过Rtti的名称获取属性的值.

我以最简单的方式实现它,但实在无法理解为什么它会向我抛出AV.

我悄悄地调试了调试器.所有类型都是它们应该是的.我只是不知道为什么TRttiProperty.GetValue破坏了破坏.

有人可以帮忙吗?单位规格;

interface

uses

Classes;

type

TPropertyExpression<TObjectType, TResultType> = class

private
  FPropertyName: string;
public
  constructor Create(aPropertyName: string); reintroduce;
  function Evaluate(aObject: TObjectType): TResultType;
  property PropertyName: string read FPropertyName write FPropertyName;
end;

procedure TestIt;

implementation

uses

Rtti;

constructor TPropertyExpression<TObjectType, TResultType>.Create(aPropertyName:
    string);
begin
  inherited Create;
  PropertyName := aPropertyName;
end;

function TPropertyExpression<TObjectType, TResultType>.Evaluate(aObject:
    TObjectType): TResultType;
var
  aCtx : TRttiContext;
  aModelType : TRttiType;
  aResultType : TRttiType;
  aProperty : TRttiProperty;
  aValue : TValue;
begin
  aCtx := TRttiContext.Create;
  aModelType := aCtx.GetType(System.TypeInfo(TObjectType));
  aResultType := …
Run Code Online (Sandbox Code Playgroud)

delphi generics rtti

1
推荐指数
1
解决办法
725
查看次数