C# 团结与修女
我试图对书面方法执行单元测试,但我面临这个问题 这是我的UnityConfig类:C# 团结与修女,c#,unit-testing,nunit,moq,unity-container,C#,Unit Testing,Nunit,Moq,Unity Container,我试图对书面方法执行单元测试,但我面临这个问题 这是我的UnityConfig类: public class UnityConfig { #region Unity Container private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => { var container = new UnityContainer();
public class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
var container = new UnityContainer();
RegisterTypes(container);
return container;
});
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
#endregion
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterInstance(AutoMapperConfig.Initialize());
container.RegisterType<IActiveDirectoryUserService, ActiveDirectoryUserService>();
container.RegisterType<IUserRepository, InMemoryUserRepository>();
container.RegisterType<IUserService, UserService>();
}
}
试验方法:
[Test]
public async Task Test()
{
var userRepositoryMock = new Mock<IUserRepository>();
var activeDirectoryUserMock = new Mock<IactiveDirectoryUserService>();
var mapperMock = new Mock<IMapper>();
var userService = new UserService(userRepositoryMock.Object, activeDirectoryUserMock.Object, mapperMock.Object);
await userService.RegisterAsync("name", "user@emial.com", "first name", "last name", "password");
userRepositoryMock.Verify(x => x.AddAsync(It.IsAny<User>()), Times.Once);
}
你知道为什么在测试过程中不使用这些方法吗?我是否需要向UnityConfig添加一些条目才能使其正常工作
-编辑
private static ISet<User> _users = new HashSet<User>
{
new User("user1", "ab@rmail.com", "firstnam1", "lastname1", "pass", "salt"),
new User("user2", "ac@rmail.com", "firstnam2", "lastname2", "pass", "salt"),
new User("user3", "ad@rmail.com", "firstnam3", "lastname3", "pass", "salt")
};
public async Task<IEnumerable<User>> GetAllAsync()
=> await Task.FromResult(_users);
发生的情况是,模拟不知道如何从异步调用返回,因此当代码试图等待它们时,它失败了。它不一定与您的DI容器有关。在本单元测试中不存在 由于没有提供有关测试中使用的类型的足够信息,因此做出一些假设 给定测试中的方法,让我们假设您有这样的接口
public interface IUserRepository {
Task<User> GetByNameAsync(string name);
Task AddAsync(User user);
}
public interface IActiveDirectoryUserService {
Task<AdUserAccount> GetByNameAsync(string name);
}
public class AdUserAccount {
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
谢谢你的回答。您假定的接口看起来与mint相同。我不明白两件事。对于userRepositoryMock,为什么要调用AddAsync方法?还有adUserMock为什么要创建假帐户?是否有其他库支持异步调用,以便我可以以更温和的方式编写测试?@ironaffee AddAsync返回一个任务。如果您没有设置它,模拟将不会返回任何内容,测试中的方法也不会流到完成状态。对于其他依赖项,情况也是如此。它的设置不正确。在测试中,对依赖项进行模拟,以便测试中的方法可以单独测试,而不会因使用具体实现而产生任何连锁反应。正在测试的方法也是异步的,因此在安排测试时需要考虑到这一点。@Iron窗帘已经解决了这一问题。我这样问是因为从你的问题历史来看,你有一个不接受答案的习惯。最后一次是在2014年。如果这个答案解决了你的问题,考虑把它标记为答案,这样帖子就可以被认为是解决了的。为什么你在ValActudioReTryUsAs= AcAudioActudieCurryUSerServ.GETBynAsAsMyCnCym返回时,为模拟广告调用创建假帐号?
private static ISet<User> _users = new HashSet<User>
{
new User("user1", "ab@rmail.com", "firstnam1", "lastname1", "pass", "salt"),
new User("user2", "ac@rmail.com", "firstnam2", "lastname2", "pass", "salt"),
new User("user3", "ad@rmail.com", "firstnam3", "lastname3", "pass", "salt")
};
public async Task<IEnumerable<User>> GetAllAsync()
=> await Task.FromResult(_users);
public interface IUserRepository {
Task<User> GetByNameAsync(string name);
Task AddAsync(User user);
}
public interface IActiveDirectoryUserService {
Task<AdUserAccount> GetByNameAsync(string name);
}
public class AdUserAccount {
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
[Test]
public async Task Test() {
//Arrrange
var name = "name";
var email = "user@emial.com";
var firstname = "first name";
var lastname = "last name";
var userRepositoryMock = new Mock<IUserRepository>();
//Testing that it returns no user for that name so return null from async call
userRepositoryMock.Setup(_ => _.GetByNameAsync(name)).ReturnsAsync((User)null);
//Need this to make sure async call runs to completion
userRepositoryMock.Setup(_ => _.AddAsync(It.IsAny<User>())).Returns(Task.FromResult((object)null));
var activeDirectoryUserMock = new Mock<IActiveDirectoryUserService>();
//fake account for mock AD call
var adUser = new AdUserAccount {
Email = email,
FirstName = firstname,
LastName = lastname
};
//Need fake ad account to return from async call
activeDirectoryUserMock.Setup(_ => _.GetByNameAsync(name)).ReturnsAsync(adUser);
var mapperMock = new Mock<IMapper>();
var userService = new UserService(userRepositoryMock.Object, activeDirectoryUserMock.Object, mapperMock.Object);
//Act
await userService.RegisterAsync(name, email, firstname, lastname, "password");
//Assert
userRepositoryMock.Verify(x => x.AddAsync(It.IsAny<User>()), Times.Once);
}