2009-09-18 178 views
3

我想创建一个托管C++单元测试项目来测试非托管MFC项目。我已阅读msujaws的程序并遵循它。我实现了一个测试方法测试的函数,像这样的返回字符串:Visual Studio 2008中的非托管C++单元测试

#include "stdafx.h" 
#include "TxStats.h" 
#include <cstdlib> 
#include <atlstr.h> 

#pragma managed 

#using <mscorlib.dll> 
#using <System.dll> 
#using <system.data.dll> 

using namespace std; 
using namespace System; 
using namespace System::Text; 
using namespace System::Text::RegularExpressions; 
using namespace System::Collections::Generic; 
using namespace System::Runtime::InteropServices; 
using namespace Microsoft::VisualStudio::TestTools::UnitTesting; 

namespace AUnitTest 
{ 
    [TestClass] 
    public ref class TxStatsTest 
    { 
    private: 
     TestContext^ testContextInstance; 

    public: 
     /// <summary> 
     ///Gets or sets the test context which provides 
     ///information about and functionality for the current test run. 
     ///</summary> 
     property Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ TestContext 
     { 
      Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ get() 
      { 
       return testContextInstance; 
      } 
      System::Void set(Microsoft::VisualStudio::TestTools::UnitTesting::TestContext^ value) 
      { 
       testContextInstance = value; 
      } 
     }; 

     #pragma region Additional test attributes 
     // 
     //You can use the following additional attributes as you write your tests: 
     // 
     //Use ClassInitialize to run code before running the first test in the class 
     //[ClassInitialize()] 
     //static void MyClassInitialize(TestContext^ testContext) {}; 
     // 
     //Use ClassCleanup to run code after all tests in a class have run 
     //[ClassCleanup()] 
     //static void MyClassCleanup() {}; 
     // 
     //Use TestInitialize to run code before running each test 
     //[TestInitialize()] 
     //void MyTestInitialize() {}; 
     // 
     //Use TestCleanup to run code after each test has run 
     //[TestCleanup()] 
     //void MyTestCleanup() {}; 
     // 
     #pragma endregion 

     [TestMethod] 
     void TestGetTxRateStr() 
     { 
      /* str to CString 

       CManagedClass* pCManagedClass = new CManagedClass(); 
       pCManagedClass->ShowMessage(strMessage); 

       char* szMessage = (char*)Marshal::StringToHGlobalAnsi(strMessage); 
       CUnmanagedClass cUnmanagedClass; cUnmanagedClass.ShowMessageBox(szMessage); 
       Marshal::FreeHGlobal((int)szMessage); 

      */ 
      CString out = TxStats::GetTxRateStr(1024); 
      // convert between MFC and .NET String implementations 
      String^myManagedString = Marshal::PtrToStringAnsi((IntPtr) (char *) out.GetBuffer()); 
      String^ret = myManagedString ;///gcnew String(); 
      Regex^matStr = gcnew Regex("1024 KB/s"); 
      StringAssert::Matches(ret, matStr); 
     } 
    }; 
} 

,测试代码在不同的项目,看起来像这样:

#include "stdafx.h" 
#include "TxStats.h" 

TxStats::TxStats() 
{ 
} 
/* 
This method returns a data rate string formatted in either Bytes, KBytes, MBytes or GBytes per sec 
from an int of the bytes per second. 
*/ 
CString TxStats::GetTxRateStr(__int64 Bps) 
{ 
enum DataUnits dunit; 
const __int64 dataSizes[]= { 0x1,  // 2^0 
     0x400,  // 2^10 
     0x100000, // 2^20 
     0x40000000};// 2^30 
const char *dataStrs[] = { "B/s", 
      "KB/s", 
      "MB/s", 
      "GB/s"}; 
CString out; 
double datarate; 
bool finish = false; 
for (dunit = A_KBYTE; dunit <= LARGER_THAN_BIGGEST_UNIT; dunit = DataUnits(dunit+1)) 
{ 
    if (dunit == LARGER_THAN_BIGGEST_UNIT) 
    { 
    if (dataSizes[dunit - 1] <= Bps) 
    { 
    //Gigabytes/sec 
    datarate = Bps/((double) dataSizes[dunit - 1]); 
    out.Format("%4.2f %s", datarate, dataStrs[dunit - 1]); 
    finish = true; 
    break; 
    } 
    } 
    else 
    { 
    if (Bps < dataSizes[dunit]) 
    { 
    //(Kilo, Mega)bytes/sec 
    datarate = Bps/((double) dataSizes[dunit - 1]); 
    out.Format("%4.2f %s", datarate, dataStrs[dunit - 1]); 
    finish = true; 
    break; 
    } 
    } 
} 
if (! finish) 
{ 
    out.Format("%s", "Unknown!"); 
} 
return out.GetBuffer(); 
} 


void TxStats::BytesToSizeStr(__int64 bytes, CString &out) 
{ 
if (bytes < 0) 
{ 
    out = "Err"; 
} 
else if (bytes == 0) 
{ 
    out = "0B"; 
} 
else 
{ 
    CString size; 
    CString byteChar = "B"; 
    CString unit; 
    int val; 
    if (bytes < 1024) 
    { 
    //Bytes 
    unit = ""; 
    val = (int)bytes; 
    } 
    else if ((bytes >> 10) < 1024) 
    { 
    //Kilobytes 
    unit = "K"; 
    __int64 div = 1 << 10; 
    val = (int) (bytes/((double) div)); 
    } 
    else if ((bytes >> 20) < 1024) 
    { 
    //Megabytes 
    unit = "M"; 
    __int64 div = 1 << 20; 
    val = (int) (bytes/((double) div)); 
    } 
    else 
    { 
    //Else assume gigabytes 
    unit = "G"; 
    __int64 div = 1 << 30; 
    val = (int) (bytes/((double) div)); 
    } 
    unit = unit + byteChar; 
    const char * unitCharBuf = unit.GetBuffer(); 
    size.Format("%d%s", ((int) val), unitCharBuf); 
    out = size.GetBuffer(); 
} 

} 

然而,当我编译这段代码我得到以下错误:

2>TxStatsTest.obj : error LNK2028: unresolved token (0A0005D4) "public: static class ATL::CStringT<char,class StrTraitMFC_DLL<char,class ATL::ChTraitsCRT<char> > > __cdecl TxStats::GetTxRateStr(__int64)" ([email protected]@@[email protected][email protected][email protected]@[email protected]@@@@[email protected]@[email protected]) referenced in function "public: void __clrcall AUnitTest::TxStatsTest::TestGetTxRateStr(void)" ([email protected]@[email protected]@$$FQ$AAMXXZ) 
2>TxStatsTest.obj : error LNK2019: unresolved external symbol "public: static class ATL::CStringT<char,class StrTraitMFC_DLL<char,class ATL::ChTraitsCRT<char> > > __cdecl TxStats::GetTxRateStr(__int64)" ([email protected]@@[email protected][email protected][email protected]@[email protected]@@@@[email protected]@[email protected]) referenced in function "public: void __clrcall AUnitTest::TxStatsTest::TestGetTxRateStr(void)" ([email protected]@[email protected]@$$FQ$AAMXXZ) 
2>\trunk\<proj>\Debug\AUnitTest.dll : fatal error LNK1120: 2 unresolved externals 
2>Caching metadata information for c:\program files\microsoft visual studio 9.0\common7\ide\publicassemblies\microsoft.visualstudio.qualitytools.unittestframework.dll... 
2>Build log was saved at "file://trunk\<proj>\AUnitTest\Debug\BuildLog.htm" 
2>AUnitTest - 3 error(s), 0 warning(s) 
========== Rebuild All: 1 succeeded, 1 failed, 0 skipped ========== 

任何人都可以说明为什么在单元测试项目可能无法连接对主体工程的OBJ文件? (我已经指定了主要项目为单元测试项目的依赖)

+0

没有任何所提供的答案帮助的连接器的输入项目的* .obj文件? – Jared 2010-11-09 01:53:17

回答

3

您可以添加

#pragma comment(lib, "TxStats.lib") 

你的单元测试项目的stdafx.cpp兑其他库链接。

+0

如果它不是作为.lib构建的,而是作为.obj(或者我可以将其更改为.lib baring,但我的其他项目是应用程序并且必须保持这种状态)。 – Jay 2009-09-19 21:58:49

+1

您可以输出.lib导入库,而不会影响其他任何内容。只需在项目的链接器选项的高级页面上指定一个文件名即可。 – 2009-09-21 17:55:58

2

您需要添加要测试的单元测试项目

相关问题