C# 无法在单元测试中从通用程序集加载类型
我在一个项目中使用了一系列通用的可移植类库。PCL的所有目标.NET4.5、Windows8、WindowsPhone8、iOS和Android。该应用程序分为几个共享项目、存储库项目和服务项目 然后,我在解决方案中添加了一个标准的单元测试项目。该项目的目标是所需的共享库以及我要测试的一个存储库库。运行测试时,我收到System.TypeLoadException:无法从程序集加载类型“BasicTaskRepository” 我有几个具有相同目标的通用PCL程序集。我可以为任何其他程序集编写单元测试,它们都可以工作并通过。出于某种原因,当我将C# 无法在单元测试中从通用程序集加载类型,c#,unit-testing,unity-container,moq,win-universal-app,C#,Unit Testing,Unity Container,Moq,Win Universal App,我在一个项目中使用了一系列通用的可移植类库。PCL的所有目标.NET4.5、Windows8、WindowsPhone8、iOS和Android。该应用程序分为几个共享项目、存储库项目和服务项目 然后,我在解决方案中添加了一个标准的单元测试项目。该项目的目标是所需的共享库以及我要测试的一个存储库库。运行测试时,我收到System.TypeLoadException:无法从程序集加载类型“BasicTaskRepository” 我有几个具有相同目标的通用PCL程序集。我可以为任何其他程序集编写单
Duty.Repositories.Tasks
程序集作为单元测试的目标时,我得到了异常
我的存储库接口和实现
namespace Duty.Repositories.Shared
{
public interface ITaskRepository
{
Task<IEnumerable<BasicTask>> GetTasks();
Task<BasicTask> GetTask(Guid taskId);
Task<BasicTask> SaveTask(BasicTask task);
Task DeleteTask(BasicTask task);
Task DeleteTask(Guid taskId);
}
}
namespace Duty.Repositories.Tasks
{
public class BasicTaskRepository : ITaskRepository
{
private ITaskService service;
public BasicTaskRepository(ITaskService service)
{
this.service = service;
}
public async Task<IEnumerable<BasicTask>> GetTasks()
{
IEnumerable<BasicTask> tasks = await this.service.GetTasks();
return tasks;
}
public async Task<BasicTask> GetTask(Guid taskId)
{
BasicTask task = await this.service.GetTask(taskId);
return task;
}
}
}
namespace Duty.Services.Shared
{
public interface ITaskService
{
Task<IEnumerable<BasicTask>> GetTasks();
Task<BasicTask> GetTask(Guid taskId);
Task<BasicTask> SaveTask(BasicTask task);
Task DeleteTask(BasicTask task);
Task DeleteTask(Guid taskId);
}
}
namespace Duty.Services.ParseCloud
{
public class TaskService : ITaskService
{
public TaskService()
{
ParseClient.Initialize("SomeKey", "AnotherKey");
}
public async Task<IEnumerable<BasicTask>> GetTasks()
{
ParseQuery<ParseObject> query = ParseObject.GetQuery(typeof(BasicTask).Name);
IEnumerable<ParseObject> parseObjects = await query.FindAsync();
// Convert the parse objects returned from the cloud into our local model representation.
// We do this in order order to maintain support for the model across multiple cloud services
// instead of restricting ourselves to the entire app using ParseCloud only.
return parseObjects.Select(po => this.ConvertParseObjectToDutyTask(po));
}
public async Task<BasicTask> GetTask(Guid taskId)
{
ParseQuery<ParseObject> query = ParseObject.GetQuery(typeof(BasicTask).Name)
.WhereEqualTo("ObjectId", taskId.ToString());
IEnumerable<ParseObject> parseObjects = await query.FindAsync();
return parseObjects.Select(po => this.ConvertParseObjectToDutyTask(po)).FirstOrDefault();
}
private BasicTask ConvertParseObjectToDutyTask(ParseObject parseObject)
{
Guid taskId = Guid.Empty;
Guid.TryParse(parseObject.ObjectId, out taskId);
return new BasicTask
{
TaskId = taskId,
Title = parseObject["Title"].ToString(),
IsCompleted = (bool)parseObject["IsCompleted"],
};
}
}
}
namespace Duty.Repositories.Shared
{
公共接口ITaskRepository
{
任务GetTasks();
任务GetTask(Guid taskId);
任务保存任务(基本任务任务);
任务删除任务(基本任务任务);
任务删除任务(Guid任务ID);
}
}
命名空间Duty.Repositories.Tasks
{
公共类BasicTaskRepository:ITaskRepository
{
私人iTask服务;
公共基本任务库(ITaskService)
{
服务=服务;
}
公共异步任务GetTasks()
{
IEnumerable tasks=等待this.service.GetTasks();
返回任务;
}
公共异步任务GetTask(Guid taskId)
{
BasicTask task=wait this.service.GetTask(taskId);
返回任务;
}
}
}
接下来是我的ITaskService接口和实现
namespace Duty.Repositories.Shared
{
public interface ITaskRepository
{
Task<IEnumerable<BasicTask>> GetTasks();
Task<BasicTask> GetTask(Guid taskId);
Task<BasicTask> SaveTask(BasicTask task);
Task DeleteTask(BasicTask task);
Task DeleteTask(Guid taskId);
}
}
namespace Duty.Repositories.Tasks
{
public class BasicTaskRepository : ITaskRepository
{
private ITaskService service;
public BasicTaskRepository(ITaskService service)
{
this.service = service;
}
public async Task<IEnumerable<BasicTask>> GetTasks()
{
IEnumerable<BasicTask> tasks = await this.service.GetTasks();
return tasks;
}
public async Task<BasicTask> GetTask(Guid taskId)
{
BasicTask task = await this.service.GetTask(taskId);
return task;
}
}
}
namespace Duty.Services.Shared
{
public interface ITaskService
{
Task<IEnumerable<BasicTask>> GetTasks();
Task<BasicTask> GetTask(Guid taskId);
Task<BasicTask> SaveTask(BasicTask task);
Task DeleteTask(BasicTask task);
Task DeleteTask(Guid taskId);
}
}
namespace Duty.Services.ParseCloud
{
public class TaskService : ITaskService
{
public TaskService()
{
ParseClient.Initialize("SomeKey", "AnotherKey");
}
public async Task<IEnumerable<BasicTask>> GetTasks()
{
ParseQuery<ParseObject> query = ParseObject.GetQuery(typeof(BasicTask).Name);
IEnumerable<ParseObject> parseObjects = await query.FindAsync();
// Convert the parse objects returned from the cloud into our local model representation.
// We do this in order order to maintain support for the model across multiple cloud services
// instead of restricting ourselves to the entire app using ParseCloud only.
return parseObjects.Select(po => this.ConvertParseObjectToDutyTask(po));
}
public async Task<BasicTask> GetTask(Guid taskId)
{
ParseQuery<ParseObject> query = ParseObject.GetQuery(typeof(BasicTask).Name)
.WhereEqualTo("ObjectId", taskId.ToString());
IEnumerable<ParseObject> parseObjects = await query.FindAsync();
return parseObjects.Select(po => this.ConvertParseObjectToDutyTask(po)).FirstOrDefault();
}
private BasicTask ConvertParseObjectToDutyTask(ParseObject parseObject)
{
Guid taskId = Guid.Empty;
Guid.TryParse(parseObject.ObjectId, out taskId);
return new BasicTask
{
TaskId = taskId,
Title = parseObject["Title"].ToString(),
IsCompleted = (bool)parseObject["IsCompleted"],
};
}
}
}
namespace Duty.Services.Shared
{
公共接口ITaskService
{
任务GetTasks();
任务GetTask(Guid taskId);
任务保存任务(基本任务任务);
任务删除任务(基本任务任务);
任务删除任务(Guid任务ID);
}
}
命名空间Duty.Services.ParseCloud
{
公共类任务服务:ITaskService
{
公共服务
{
初始化(“SomeKey”、“AnotherKey”);
}
公共异步任务GetTasks()
{
ParseQuery=ParseObject.GetQuery(typeof(BasicTask).Name);
IEnumerable parseObjects=wait query.FindAsync();
//将从云返回的解析对象转换为本地模型表示。
//我们这样做是为了跨多个云服务维护对模型的支持
//而不是仅使用ParseCloud将自己局限于整个应用程序。
返回parseObjects.Select(po=>this.ConvertParseObjectToDutyTask(po));
}
公共异步任务GetTask(Guid taskId)
{
ParseQuery=ParseObject.GetQuery(typeof(BasicTask).Name)
.WhereEqualTo(“ObjectId”,taskId.ToString());
IEnumerable parseObjects=wait query.FindAsync();
返回parseObjects.Select(po=>this.ConvertParseObjectToDutyTask(po)).FirstOrDefault();
}
私有BasicTask ConvertParseObjectToDutyTask(ParseObject ParseObject)
{
Guid taskId=Guid.Empty;
Guid.TryParse(parseObject.ObjectId,out taskId);
返回新的基本任务
{
TaskId=TaskId,
Title=parseObject[“Title”]。ToString(),
IsCompleted=(bool)parseObject[“IsCompleted”],
};
}
}
}
最后,我的两个单元测试。访问存储库的单元测试失败,出现上述异常,而访问服务的单元测试每次都直接通过
public class BasicTaskRepositoryTests
{
private ITaskService taskService;
[TestInitialize]
public void Setup()
{
var basicTasks = new List<BasicTask>()
{
new BasicTask { Title = "Test Title 1", TaskId = Guid.Empty },
new BasicTask { Title = "Test Title 2", TaskId = Guid.Empty, },
};
var serviceMock = new Mock<ITaskService>();
// Set up our mock service object.
serviceMock.Setup(service => service.GetTasks()).ReturnsAsync(basicTasks);
serviceMock.Setup(service => service.GetTask(It.IsAny<Guid>()))
.ReturnsAsync(basicTasks.FirstOrDefault());
serviceMock.Setup(service => service.SaveTask(It.IsAny<BasicTask>()))
.ReturnsAsync(basicTasks.FirstOrDefault());
serviceMock.Setup(service => service.DeleteTask(It.IsAny<BasicTask>()))
.Returns<BasicTask>(null);
this.taskService = serviceMock.Object;
}
[TestMethod]
public async Task TaskRepository_GetBasicTasks_HasTasks()
{
// Arrange
var taskRepository = new Duty.Repositories.Tasks.BasicTaskRepository(taskService);
// Act
IEnumerable<BasicTask> tasks = await taskRepository.GetTasks();
// Assert
Assert.AreEqual<int>(2, tasks.Count());
}
[TestMethod]
public async Task TaskService_GetBasicTasks_HasTasks()
{
// Arrange
var serviceRepo = new Services.ParseCloud.TaskService();
// Act
IEnumerable<BasicTask> tasks = await serviceRepo.GetTasks();
// Assert
Assert.AreEqual(2, tasks.Count());
}
}
公共类BasicTaskRepositoryTests
{
私人ITaskService任务服务;
[测试初始化]
公共作废设置()
{
var basicTasks=新列表()
{
新的基本任务{Title=“测试标题1”,TaskId=Guid.Empty},
新的基本任务{Title=“测试标题2”,TaskId=Guid.Empty,},
};
var serviceMock=new Mock();
//设置我们的模拟服务对象。
serviceMock.Setup(service=>service.GetTasks()).ReturnsAsync(basicTasks);
serviceMock.Setup(service=>service.GetTask(It.IsAny()))
.ReturnsAsync(basicTasks.FirstOrDefault());
serviceMock.Setup(service=>service.SaveTask(It.IsAny()))
.ReturnsAsync(basicTasks.FirstOrDefault());
serviceMock.Setup(service=>service.DeleteTask(It.IsAny()))
.返回(空);
this.taskService=serviceMock.Object;
}
[测试方法]
公共异步任务任务库\u GetBasicTasks\u HasTasks()
{
//安排
var taskRepository=new Duty.Repositories.Tasks.BasicTaskRepository(taskService);
//表演
IEnumerable tasks=wait taskRepository.GetTasks();
//断言
aresequal(2,tasks.Count());
}
[测试方法]
公共异步任务TaskService_GetBasicTasks_HasTasks()
{
//安排
var serviceRepo=new Services.ParseCloud.TaskService();
//表演
IEnumerable tasks=wait serviceRepo.GetTasks();
//断言
aresequal(2,tasks.Count());
}
}
同样,我所有的库都是针对.NET4.5、Windows8、WindowsPhone8.1、iOS和Android的PCL。服务PCL和存储库PCL之间没有目标差异。单元测试项目是一个标准的单元测试(非Windows Universal),但我很难发现这是一个问题,因为服务测试毫无疑问地引用了Universal PCL
我已经从解决方案中删除了Repositories项目,重新构建并重新运行了测试(如建议的),然后重新添加了该项目;这并没有解决问题
我删除了整个项目
Solution
|___Repositories
|_______Duty.Repositories.Tasks
|___Tests
|______Repositories
|___________Duty.Repositories.Tasks