2009-09-18 113 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

您需要添加要測試的單元測試項目

相關問題