新浪微博客户端围脖七开发笔记(2) 添加更多测试到MainPageViewModel

想了一个礼拜,究竟是先实现些具体功能呢,还是继续完善TDD,还是先后者吧:具体功能无非就是些api的调用,wp7的twiter或者围脖的例子也有一些了,也不少我这一篇:)

1. 准备几个基本类,status,user和SinaService接口

代码
public class User
{
public ulong Id { get; set; }
public string ScreenName { get; set; }
public string ImageUrl { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public int Followers { get; set; }
public int Friends { get; set; }
public DateTime CreatedAt { get; set; }
}

public class Status
{
public Status()
{
User
= new User();
}

public DateTime CreatedAt { get; set; }

public ulong Id { get; set; }

public string Text { get; set; }

public string Source { get; set; }

public User User { get; set; }

public bool Favorited { get; set; }

public int RetweetCount { get; set; }

public bool Retweeted { get; set; }

}

/// <summary>
/// A simple Sina service interface
/// </summary>
public interface ISinaService
{
/// <summary>
/// Get statuses from sina weibo
/// </summary>
/// <param name="onGetStatusesCompleted">the callback method</param>
/// <param name="onError"></param>
/// <param name="onFinally"></param>
void GetStatuses(Action<IEnumerable<Status>> onGetStatusesCompleted = null, Action<Exception> onError = null, Action onFinally = null);
}

status和user类的相应测试俺就偷懒不写了,读者有兴趣可以自己试试!

 

2. 修改下MainPageViewModel, 加入SinaService接口和HomeList,前者用来调用sina的接口取得数据,后者是最新微博的容器。注意把它们设置为internal,方便测试项目调用,还要添加如下一行在AssemblyInfo.cs中:

[assembly: InternalsVisibleTo("WeiBo7.Test")]

 

代码
public class MainPageViewModel : ViewModelBase
{
internal readonly ISinaService SinaService;
private bool _isHomeRefreshing = false;

public MainPageViewModel()
{
SinaService
= new SinaService();
HomeList
= new ObservableCollection<Status>();

}

public ObservableCollection<Status> HomeList { get; internal set; }

/// <summary>
/// Indicates whether there is an indeterminate operation in progress
/// </summary>
public bool IsHomeRefreshing
{
get { return _isHomeRefreshing; }
set
{
if (value != _isHomeRefreshing)
{
_isHomeRefreshing
= value;
OnNotifyPropertyChanged(
"IsHomeRefreshing");
}
}
}

}

3. 现在转到测试项目,先加入一个TestInitialize方法,在所有的测试方法前做些准备工作:

 

private MainPageViewModel _mainViewModel;

[TestInitialize]
public void Initialize()
{
_mainViewModel
= new MainPageViewModel();
}

还可以加入一个[TestCleanup]方法:

[TestCleanup]
public void CleanUp()
{

}

目前没干什么事情,但对于任何一个测试方法,执行顺序是TestInitialize->test method->TestCleanup, 这样保证每个测试方法是彼此独立,互不影响,不用在每个测试方法里面都初始化,节省些代码。

4. 在MainPageViewModelTests先添加一个negative test, 看下这个类如何应对NullInstance

 

代码
[TestMethod]
[ExpectedException(
typeof(NullReferenceException))]
public void NullInstance()
{
_mainViewModel
= null;
bool x = _mainViewModel.IsHomeRefreshing;
}

5. 测试初始化是否成功

 

代码
[TestMethod]
public void Init_MainPageViewModel_Success()
{
Assert.IsNotNull(_mainViewModel);
Assert.IsNotNull(_mainViewModel.HomeList);
Assert.IsNotNull(_mainViewModel.SinaService);
Assert.IsInstanceOfType(_mainViewModel,
typeof(INotifyPropertyChanged));
}

 6. 测试当添加一个item到HomeList时,是否CollectionChanged被fire 

 

代码
[TestMethod]
public void AddItem_HomeList_RaisesCollectionChanged()
{
bool changeObserved = false;
_mainViewModel.HomeList.CollectionChanged
+=
(s, e)
=>
{
changeObserved
= true;
Assert.AreEqual(NotifyCollectionChangedAction.Add, e.Action);
Assert.AreEqual(
1, e.NewItems.Count, "only should be +1 item");
};

_mainViewModel.HomeList.Add(
new Status());
Assert.IsTrue(changeObserved);
}
最后运行如下图:


posted @ 2010-11-19 23:50  上尉  阅读(1655)  评论(0编辑  收藏  举报
View Hao Wang's profile on LinkedIn