Unit testing 我应该在什么时候声明SUT的操作?
考虑以下单元测试:Unit testing 我应该在什么时候声明SUT的操作?,unit-testing,moq,Unit Testing,Moq,考虑以下单元测试: [Test] public void Success() { var userID = 5; var user = new User(); var dataAccess = new Mock<IDataAccess>(); dataAccess.Setup(x => x.GetUser(userID)).Returns(user).Verifiable(); var sut = new UserController(dataAccess.
[Test]
public void Success()
{
var userID = 5;
var user = new User();
var dataAccess = new Mock<IDataAccess>();
dataAccess.Setup(x => x.GetUser(userID)).Returns(user).Verifiable();
var sut = new UserController(dataAccess.Object);
var returnedUser = sut.GetUser(userID);
Assert.AreSame(user, returnedUser);
dataAccess.Verify(x => x.GetUser(userID), Times.Once());
}
[测试]
公开募捐成功()
{
var userID=5;
var user=新用户();
var dataAccess=new Mock();
dataAccess.Setup(x=>x.GetUser(userID)).Returns(user.Verifiable();
var sut=newusercontroller(dataAccess.Object);
var returnedUser=sut.GetUser(userID);
Assert.AreName(用户,返回用户);
验证(x=>x.GetUser(userID),Times.Once());
}
最近的阅读表明,我应该只使用mock来提供给用户,并且应该有一个断言(AreSame)。显然,理想的单元测试不应该担心验证sut的行为
更像这样:
[Test]
public void Success()
{
var userID = 5;
var user = new User();
var dataAccess = new Mock<IDataAccess>();
dataAccess.Setup(x => x.GetUser(userID)).Returns(user);
var sut = new UserController(dataAccess.Object);
var returnedUser = sut.GetUser(userID);
Assert.AreSame(user, returnedUser);
}
[测试]
公开募捐成功()
{
var userID=5;
var user=新用户();
var dataAccess=new Mock();
Setup(x=>x.GetUser(userID)).Returns(user);
var sut=newusercontroller(dataAccess.Object);
var returnedUser=sut.GetUser(userID);
Assert.AreName(用户,返回用户);
}
这个简化测试更好吗?单元测试应该断言它们调用的方法的行为,还是仅仅断言结果?一个基本思想是在测试中只有一个断言。所以也许你应该考虑两个测试。第一个基于值的测试很重要。第二个交互测试可能不适合这种情况。Roy Osherove说:“当调用另一个对象是特定工作单元的最终结果时,使用交互测试。” 例如:
namespace Tests
{
[TestClass]
public class UserControllerTest
{
[TestMethod]
public void GetUser_WhenCalled_ReturnsUserSameAsDataAccess()
{
// Arrange
const int userID = 5;
User expectedUser = new User();
Mock<IDataAccess> dataAccessStub = new Mock<IDataAccess>();
dataAccessStub.Setup(x => x.GetUser(userID)).Returns(expectedUser);
UserController controller = new UserController(dataAccessStub.Object);
// Act
User actualUser = controller.GetUser(userID);
// Assert
Assert.AreSame(expectedUser, actualUser);
}
[TestMethod]
public void GetUser_WhenCalled_GetUserOnDataAccessIsCalledOnce()
{
// Arrange
const int userID = 5;
const int getUserCallsCountExpected = 1;
int getUserCallsCount = 0;
Mock<IDataAccess> dataAccessMock = new Mock<IDataAccess>();
dataAccessMock.Setup(x => x.GetUser(userID)).Callback(() => getUserCallsCount++);
UserController controller = new UserController(dataAccessMock.Object);
// Act
controller.GetUser(userID);
// Assert
Assert.AreEqual(getUserCallsCountExpected, getUserCallsCount);
}
}
}
命名空间测试
{
[测试类]
公共类UserControllerTest
{
[测试方法]
public void GetUser\u当调用时返回susersameasdataaccess()
{
//安排
const int userID=5;
用户expectedUser=新用户();
Mock dataAccessStub=new Mock();
Setup(x=>x.GetUser(userID)).Returns(expectedUser);
UserController=newusercontroller(dataAccessStub.Object);
//表演
User actualUser=controller.GetUser(userID);
//断言
Assert.AreName(预期用户、实际用户);
}
[测试方法]
public void GetUser\u调用时\u GetUserOnDataAccessIsCalledOnce()
{
//安排
const int userID=5;
const int getUserCallsCountExpected=1;
int getUserCallsCount=0;
Mock dataAccessMock=new Mock();
dataAccessMock.Setup(x=>x.GetUser(userID)).Callback(()=>getusercallscont++);
UserController=新的UserController(dataAccessMock.Object);
//表演
controller.GetUser(userID);
//断言
AreEqual(getUserCallsCountExpected,getUserCallsCount);
}
}
}
可能重复的,这是一篇很好的背景文章:我同意第一次测试。但我总是很难理解第二次测试增加了什么价值?它不是在测试API的内部实现吗?这个测试对重构有弹性吗?只要公众行为没有改变,单元测试不应该继续通过吗?@Amol是的,我认为你是对的,第二个测试可能不适合这种情况。我编辑了答案。