我正试图掌握Moq并使用一个简单的例子来弄明白。我正在使用Google对地址进行地理编码。我已经包装了WebClient,因此可以进行模拟。这是代码:
public class Position
{
public Position(double latitude, double longitude)
{
Latitude = latitude;
Longitude = longitude;
}
public virtual double Latitude { get; private set; }
public virtual double Longitude { get; private set; }
}
public interface IWebDownloader
{
string Download(string address);
}
public class WebDownloader : IWebDownloader
{
public WebDownloader()
{
WebProxy wp = new WebProxy("proxy", 8080);
wp.Credentials = new NetworkCredential("user", "password", "domain");
_webClient = new WebClient();
_webClient.Proxy = wp;
}
private WebClient _webClient = null;
#region IWebDownloader Members
public string Download(string address)
{
return Encoding.ASCII.GetString(_webClient.DownloadData(address));
}
#endregion
}
public class Geocoder
{
public Position GetPosition(string address, IWebDownloader downloader)
{
string url = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?address={0}&sensor=false",
address);
string xml = downloader.Download(url);
XDocument doc = XDocument.Parse(xml);
var position = from p in doc.Descendants("location")
select new Position(
double.Parse(p.Element("lat").Value),
double.Parse(p.Element("lng").Value)
);
return position.First();
}
}
到目前为止一切顺利。现在这是Moq的单元测试:
[TestMethod()]
public void GetPositionTest()
{
Mock<IWebDownloader> mockDownloader = new Mock<IWebDownloader>(MockBehavior.Strict);
const string address = "Brisbane, Australia";
mockDownloader.Setup(w => w.Download(address)).Returns(Resource1.addressXml);
IWebDownloader mockObject = mockDownloader.Object;
Geocoder geocoder = new Geocoder();
Position position = geocoder.GetPosition(address, mockObject);
Assert.AreEqual(position.Latitude , -27.3611890);
Assert.AreEqual(position.Longitude, 152.9831570);
}
返回值位于资源文件中,是Google的XML输出。现在,当我运行单元测试时,我得到了异常:
模拟上的所有调用都必须有相应的设置..
如果我关闭严格模式,则模拟对象返回null。如果我将设置更改为:
mockDownloader.Setup(w => w.Download(It.IsAny<string>())).Returns(Resource1.addressXml);
然后测试运行正常。但我不想测试任何字符串,我想测试这个特定的地址。
请把我从痛苦中解脱出来告诉我哪里出错了。
答案 0 :(得分:3)
据我所知,当你收到字符串“Brisbane,Australia”时,你的模拟返回值是一个特定值,但你传递的值是http://maps.googleapis.com/maps/api/geocode/xml?address=Brisbane,%20Australia&sensor=false
(或者它最终会格式化。)
在测试代码中尝试这样的事情:
…
const string address = "Brisbane, Australia";
const string url = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?address={0}&sensor=false", address);
mockDownloader.Setup(w => w.Download(url)).Returns(Resource1.addressXml);
…