Модульный тест должен протестировать единственный путь выполнения кода через отдельный метод. Когда осуществление метода передает за пределами того метода в другой объект, и назад снова, у Вас есть зависимость.
при тестировании того пути выполнения кода с фактической зависимостью Вы не поблочное тестирование; Вы - интеграционное тестирование. В то время как это хорошо и необходимо, это не поблочное тестирование.
, Если Ваша зависимость является багги, Ваш тест может быть затронут таким способом возвратить положительный false. Например, можно передать зависимость неожиданный пустой указатель, и зависимость не может бросить на пустой указатель, поскольку это документируется, чтобы сделать. Ваш тест не делает enounter исключение нулевого аргумента, как это должно иметь, и тестовые передачи.
кроме того, можно найти его твердое, если не невозможный, для надежного получения зависимого объекта возвратить точно, что Вы хотите во время теста. Это также включает ожидаемые исключения броска в тестах.
насмешка А заменяет ту зависимость. Вы устанавливаете ожидания по вызовам к зависимому объекту, установите точные возвращаемые значения, которые он должен дать Вам для выполнения теста, который Вы хотите, и/или какие исключения выдать так, чтобы можно было протестировать код обработки исключений. Таким образом можно протестировать рассматриваемую единицу легко.
TL; DR: Дразните каждую зависимость Ваши касания модульного теста.
Вместо этого вам нужно создать BSTR. Строки VB6 на самом деле являются BSTR. Вызовите SysAllocString () на стороне Delphi и верните BSTR на сторону VB6. Сторона VB6 должна будет вызвать SysFreeString () для освобождения строки - она сделает это автоматически.
Если PChar соответствует строке ANSI (в вашем случае), вы должны вручную преобразовать ее в Unicode - используйте для этого MultiByteToWideChar () . См. этот ответ , чтобы узнать, как лучше использовать SysAllocStringLen () и MultiByteToWideChar () вместе.
Объединение ответа Sharptooth и Lars D; разве широкие строки уже не выделены через окна и BSTR?
Если вы не хотите рисковать сбоями или утечками памяти, создайте свой API, используя Windows API в качестве модели. Там функции API обычно не выделяют собственную память. Вместо этого вызывающий передает буфер и сообщает API, насколько велик буфер. API заполняет буфер до этого предела. См., Например, функцию GetWindowText
. Функции не возвращают указатели , если только они не являются указателями на вещи, которые уже предоставил вызывающий. Вместо этого вызывающий предоставляет все сам, и функция просто использует то, что ей дано. Вы почти никогда не увидите параметр выходного буфера, который не сопровождается другим параметром, указывающим размер буфера.
Еще одно усовершенствование, которое вы можете внести в этот метод, - разрешить функции сообщать вызывающему, насколько велик буфер должен быть. Когда входной указатель является нулевым указателем, функция может возвращать количество байтов, которое необходимо предоставить вызывающему. Вызывающий вызовет функцию дважды.
Вам не нужно создавать свой API с нуля. Используйте уже работающие API в качестве примеров того, как раскрыть свои собственные.
Еще одно усовершенствование, которое вы можете внести в этот метод, - это позволить функции сообщать вызывающей стороне, какой размер буфера должен быть. Когда входной указатель является нулевым указателем, функция может возвращать количество байтов, которое необходимо предоставить вызывающему. Вызывающий вызовет функцию дважды.
Вам не нужно создавать свой API с нуля. Используйте уже работающие API в качестве примеров того, как раскрыть свои собственные.
Еще одно усовершенствование, которое вы можете внести в этот метод, - это позволить функции сообщать вызывающей стороне, какой размер буфера должен быть. Когда входной указатель является нулевым указателем, функция может возвращать количество байтов, которое необходимо предоставить вызывающему. Вызывающий вызовет функцию дважды.
Вам не нужно создавать свой API с нуля. Используйте уже работающие API в качестве примеров того, как раскрыть свои собственные.
I ' m не знаком с Dephi, но вот два основных варианта использования строк с не-COM DLL и VB6.
Вариант 1. Используйте строки "ANSI".
'DLL routine expecting to be passed pointers to ANSI strings '
'VB6 will allocate and deallocate the strings '
'Its vital that VB6 allocates sufficient space for the return string '
Declare Sub MyProc Lib "mylib.dll" (ByVal Param As String, _
ByVal OutVal As String)
Function DoMyProc(ByVal Param As String) As String
Dim sResult As String
sResult = Space$(255) ' create 255 bytes of space for the return string '
Call MyProc(Param, sResult)
DoMyProc = sResult
End Function
Вариант второй. Используйте BSTR.
'DLL routine expecting to be passed two BSTRs. It will modify the second one. '
'VB6 "owns" both BSTRs and will deallocate them when it has finished with them. '
Declare Sub MyProc(ByVal lpParam As Long, ByVal lpOutVal As Long)
Function DoMyProc(ByVal Param As String) As String
Dim sResult As String
Call MyProc(StrPtr(Param), StrPtr(sResult))
DoMyProc = sResult
End Function
Я бы также посоветовал ознакомиться с советом Microsoft по написанию C DLL, которые будут вызываться из VB. Первоначально выпущен с VB5, но все еще актуален для VB6.
Используйте Windows API для выделения памяти, на которую указывает указатель PChar. Затем приложение VB может освободить память после использования, также используя Windows API.
Я бы сказал, что тот, кто выделяет память, должен также освободить ее в этом случае. Вы столкнетесь с проблемами в других сценариях. Таким образом, наиболее безопасный и чистый способ:
Настройка будет такой:
unit DLL;
interface
uses
SysUtils;
function Execute(const Params: PChar): PChar; stdcall;
procedure FreePointer(const P: PChar); stdcall;
exports Execute;
exports FreePointer;
implementation
function Execute(const Params: PChar): PChar; stdcall;
var
Size: Cardinal;
begin
Size := Calculate the size;
GetMem(Result, Size);
...do something to fill the buffer
end;
procedure FreePointer(const P: PChar); stdcall;
begin
FreeMem(P);
end;
end.
Вы не можете вернуть PChar как результат функции, но можете передать дополнительный параметр PChar и скопировать строку, которую хотите вернуть, в этот PChar. Обратите внимание, что VB должен выделить эту строку до требуемого размера, прежде чем передавать ее в dll. Также в VB этот параметр должен быть объявлен как byval param как строка И он должен быть передан с byval:
param = "aaaaaaaaaaaaaaaaaaaa" ' reserve 20 characters
call myproc(byval param)
Дополнительный byval в вызове будет выполнять магию компилятора преобразования строки VB в PChar и обратно.
( Надеюсь, я правильно помню, прошло много времени с тех пор, как я был вынужден использовать VB.)